Pacman on an 8x8 LED Matrix

Post here to let others know of a project you're working on.

Moderators: Chuckt, Garth, bitfogav

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Pacman on an 8x8 LED Matrix

Post by brad » Mon Jul 12, 2010 10:17 pm

Hi guys, I have been working on a simple mock-up of the original pacman game. At the moment I am using an RG 8x8 LED matrix but will almost certainly use an RGB for the final version.

At the moment you are able to move about the screen (which has a total game area of 32 x 32 pixels) if the screen is at any of the extremes, it will allow just your pacman (a single pixel) to move around. If you try and move any further away from an extreme edge of screen, it will be the whole screen that shifts to reveal more of the 32 x 32 pixel area.

An animated gif (although poor quality) says it better than text: please note that this animation is running at a very reduced frame rate and as such can be hard to follow what is happening on the display.

Image

I have also made it so that you can warp from screen edge to screen edge (just like in the original game)

i have started to experiment with one 'ghost' (bad guy) on the screen. At the moment he just follows you everywhere but doesnt hurt you (a simple x and y co-ordinate system whereby the ghost keeps checking to see if his x and y co-ordinates are greater or less than yours in order to seek you out.)

Eventually I will make it so that there are multiple ghosts who will follow you around (while also avoiding walls rather than going through them.

And of course, there will be loads of levels and pellets to eat along the way.

Here is the basic sourcecode (so far):

Code: Select all

Device = 18F4685         // Tell the compiler what chip we are using
Clock = 8                // Tell the compiler what we will be setting the clock to (Mhz)           
Config OSC = IRCIO67     // This tells the microcontroller to use the internal clock 

Include "utils.bas"      // we are including an extra file here which allows us to use shortcuts
                         // like "SetAllDigital" Which will take care of making all ports digital ports.                      

Const graphic_data(32) As LongWord = (%11111111111111111111111111111111,
%10000000000001111110000000000001,
%10111101111101111110111110111101,
%10111101111101111110111110111101,
%10111101111101111110111110111101,
%10000000000000000000000000000001,
%10111101110111111111101110111101,
%10111101110111111111101110111101,
%10000001110000111100001110000001,
%11111101111110111101111110111111,
%00000101111110111101111110100000,
%00000101110000000000001110100000,
%00000101110111111111101110100000,
%11111101110111111111101110111111,
%00000000000111111111100000000000,
%11111101110111111111101110111111,
%00000101110000000000001110100000,
%00000101110101111110101110100000,
%00000101110100001000101110100000,
%00000101110111101011101110100000,
%11111101110111101011101110111111,
%10000000000000001000000000000001,
%10111101111101101011011111011101,
%10111101111101100011011111011101,
%10001101111101110111011111010001,
%11101101111101110111011111010111,
%11100000000000000000000000000111,
%11101111011111111111111011110111,
%10001111000001111110000011110001,
%10111111111101111110111111111101,
%10000000000000000000000000000001,
%11111111111111111111111111111111)                        
Const anodes(8) As Byte = (%00000001,%00000010,%00000100,%00001000,%00010000,%00100000,%01000000,%10000000) 

// variable declaration
Dim x As Byte
Dim current_graphic_byte As Byte
Dim old_graphic_byte As Byte
Dim frame_counter As Byte
Dim button_debounce As Byte
Dim car_data As Byte
Dim game_over As Byte
Dim crash_result As Byte
Dim shift_register As LongWord
Dim shift As Byte
Dim character_x As Byte
Dim character_y As Byte
Dim character_x_position As Byte
Dim wall_data As Byte
Dim wall_data_above As Byte
Dim wall_data_below As Byte
Dim wall_flags As Byte
Dim wall_up As wall_flags.0
Dim wall_down As wall_flags.1
Dim wall_left As wall_flags.2
Dim wall_right As wall_flags.3

Dim board_position_x As Byte
Dim board_position_y As Byte
Dim character_area_x As Byte
Dim character_area_y As Byte
Dim enemy_1_area_x As Byte
Dim enemy_1_area_y As Byte

Dim enemy_on_screen_x As Byte
Dim enemy_on_screen_y As Byte

Dim enemy_delay_x As Byte
Dim enemy_delay_y As Byte

// Port Setup
Dim up As PORTA.0
Dim down As PORTA.1
Dim left As PORTA.2
Dim right As PORTA.3

Dim common_anodes As PORTD
Dim green_cathodes As PORTB
Dim red_cathodes As PORTC

// Sub Routines
Sub draw_graphics()
    For x = 0 To 7
        common_anodes = anodes(x)
        shift_register = graphic_data(current_graphic_byte)
        Select shift
            Case 1
                shift_register = shift_register >> 1
            Case 2
                shift_register = shift_register >> 2
            Case 3
                shift_register = shift_register >> 3
            Case 4
                shift_register = shift_register >> 4
            Case 5
                shift_register = shift_register >> 5
            Case 6
                shift_register = shift_register >> 6
            Case 7
                shift_register = shift_register >> 7
            Case 8
                shift_register = shift_register >> 8
            Case 9
                shift_register = shift_register >> 9
            Case 10
                shift_register = shift_register >> 10
            Case 11
                shift_register = shift_register >> 11
            Case 12
                shift_register = shift_register >> 12
            Case 13
                shift_register = shift_register >> 13
            Case 14
                shift_register = shift_register >> 14
            Case 15
                shift_register = shift_register >> 15
            Case 16
                shift_register = shift_register >> 16
            Case 17
                shift_register = shift_register >> 17
            Case 18
                shift_register = shift_register >> 18
            Case 19
                shift_register = shift_register >> 19
            Case 20
                shift_register = shift_register >> 20
            Case 21
                shift_register = shift_register >> 21
            Case 22
                shift_register = shift_register >> 22
            Case 23
                shift_register = shift_register >> 23
            Case 24
                shift_register = shift_register >> 24
        End Select
        shift_register = shift_register Xor %11111111   // need to invert the data since we are using common cathodes  
        green_cathodes = shift_register
        shift_register = shift_register Xor %11111111   // invert back to aid in checking for walls
        If x = character_y Then
            wall_data = shift_register                  // once we have found what data is in the same row as us, save it for later.
            red_cathodes = character_x
        ElseIf x = character_y + 1 Then
            wall_data_above = shift_register
        ElseIf x = character_y - 1 Then
            wall_data_below = shift_register            
        EndIf
        If x = enemy_on_screen_y And enemy_on_screen_x < 8 Then
            red_cathodes.bits(enemy_on_screen_x) = 0    
        EndIf
        DelayMS(1)
        red_cathodes = %11111111
        green_cathodes = %11111111                               // clear the video ram before changing columns
        Inc(current_graphic_byte)
        If x = 7 Then                                            // reset back to the first column in this frame
            current_graphic_byte = old_graphic_byte
        EndIf
    Next          
End Sub  

Sub update_character()
    Select character_x_position
        Case 0
            character_x = %11111110
        Case 1
            character_x = %11111101
        Case 2
            character_x = %11111011
        Case 3
            character_x = %11110111
        Case 4
            character_x = %11101111
        Case 5
            character_x = %11011111
        Case 6
            character_x = %10111111
        Case 7
            character_x = %01111111
    End Select
End Sub

Sub update_enemy_x()        
    enemy_on_screen_x = enemy_1_area_x - board_position_x    
    If enemy_1_area_x > character_area_x And enemy_delay_x = 0 Then
        Dec(enemy_1_area_x)
        enemy_delay_x = 50
    ElseIf enemy_1_area_x < character_area_x And enemy_delay_x = 0 Then
        Inc(enemy_1_area_x)
        enemy_delay_x = 50
    EndIf
End Sub

Sub update_enemy_y()
    enemy_on_screen_y = enemy_1_area_y - board_position_y
    If enemy_1_area_y > character_area_y And enemy_delay_y = 0 Then
        Dec(enemy_1_area_y)
        enemy_delay_y = 50
    ElseIf enemy_1_area_y < character_area_y And enemy_delay_y = 0 Then
        Inc(enemy_1_area_y)
        enemy_delay_y = 50
    EndIf
End Sub

Sub check_buttons()
    If button_debounce = 0 And left = 0 And character_x_position < 3 And shift = 0 And wall_left = 0 Then
        Inc(character_x_position)
        Inc(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And left = 0 And character_x_position > 3 And shift < 24 And shift > 0 And wall_left = 0 Then
        Inc(shift)
        Inc(board_position_x)
        Inc(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And left = 0 And shift = 24 And character_x_position > 2  And character_x_position < 7 And wall_left = 0 Then
        Inc(character_x_position)
        Inc(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And left = 0 And character_x_position = 3 And shift <> 24 And wall_left = 0 Then
        Inc(shift)
        Inc(board_position_x)
        Inc(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And left = 0 And character_x_position = 4 And shift <> 24 And wall_left = 0 Then
        Inc(shift)
        Inc(board_position_x)
        Inc(character_area_x)
        button_debounce = 15
    EndIf
    

    If button_debounce = 0 And right = 0 And character_x_position > 4 And shift = 24 And wall_right = 0 Then
        Dec(character_x_position)
        Dec(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And right = 0 And character_x_position < 4 And shift < 24 And shift > 0 And wall_right = 0 Then
        Dec(shift)
        Dec(board_position_x)
        Dec(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And right = 0 And shift = 0 And character_x_position < 5 And character_x_position > 0 And wall_right = 0 Then
        Dec(character_x_position)
        Dec(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And right = 0 And character_x_position = 4 And shift <> 0 And wall_right = 0 Then
        Dec(shift)
        Dec(board_position_x)
        Dec(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And right = 0 And character_x_position = 3 And shift <> 0 And wall_right = 0 Then
        Dec(shift)
        Dec(board_position_x)
        Dec(character_area_x)
        button_debounce = 15
    EndIf     
    
    If button_debounce = 0 And up = 0 And character_y < 3 And current_graphic_byte = 0 And wall_up = 0 Then
        Inc(character_y)
        Inc(character_area_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And up = 0 And character_y > 3 And current_graphic_byte < 24 And current_graphic_byte > 0 And wall_up = 0 Then
        Inc(current_graphic_byte)
        Inc(old_graphic_byte)
        Inc(character_area_y)
        Inc(board_position_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And up = 0 And current_graphic_byte = 24 And character_y > 2  And character_y < 6 And wall_up = 0 Then
        Inc(character_y)
        Inc(character_area_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And up = 0 And character_y = 3 And current_graphic_byte <> 24 And wall_up = 0 Then
        Inc(current_graphic_byte)
        Inc(old_graphic_byte)
        Inc(character_area_y)
        Inc(board_position_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And up = 0 And character_y = 4 And current_graphic_byte <> 24 And wall_up = 0 Then
        Inc(current_graphic_byte)
        Inc(old_graphic_byte)
        Inc(character_area_y)
        Inc(board_position_y)
        button_debounce = 15
    EndIf
    
    If button_debounce = 0 And down = 0 And character_y > 4 And current_graphic_byte = 24 And wall_down = 0 Then
        Dec(character_y)
        Dec(character_area_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And down = 0 And character_y < 4 And current_graphic_byte < 24 And current_graphic_byte > 0 And wall_down = 0 Then
        Dec(current_graphic_byte)
        Dec(old_graphic_byte)
        Dec(character_area_y)
        Dec(board_position_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And down = 0 And current_graphic_byte = 0 And character_y < 5  And character_y > 1 And wall_down = 0 Then
        Dec(character_y)
        Dec(character_area_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And down = 0 And character_y = 4 And current_graphic_byte <> 0 And wall_down = 0 Then
        Dec(current_graphic_byte)
        Dec(old_graphic_byte)
        Dec(character_area_y)
        Dec(board_position_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And down = 0 And character_y = 3 And current_graphic_byte <> 0 And wall_down = 0 Then
        Dec(current_graphic_byte)
        Dec(old_graphic_byte)
        Dec(character_area_y)
        Dec(board_position_y)
        button_debounce = 15
    EndIf             
End Sub

Sub debounce_buttons()
    If button_debounce <> 0 Then
        Dec(button_debounce)
    EndIf
End Sub

Sub enemy_delay_time()
    If enemy_delay_x <> 0 Then
        Dec(enemy_delay_x)
    EndIf
    If enemy_delay_y <> 0 Then
        Dec(enemy_delay_y)
    EndIf
End Sub

Sub check_for_walls()
    For x = 0 To 7 
        If character_x_position = x Then
            If wall_data_above.bits(x) = 1 Then
                wall_up = 1
            ElseIf wall_data_above.bits(x) = 0 Then
                wall_up = 0
            EndIf
            If wall_data_below.bits(x) = 1 Then
                wall_down = 1
            ElseIf wall_data_below.bits(x) = 0 Then
                wall_down = 0
            EndIf
        EndIf
    Next
                    
    For x = 0 To 6
        If character_x_position = (x) And wall_data.bits(x + 1) = 1 Then           // these first two check for
            wall_left = 1                                                               // walls to the left
        ElseIf character_x_position = (x) And wall_data.bits(x + 1) = 0 Then                                              
            wall_left = 0
        ElseIf character_x_position = (x + 1) And wall_data.bits(x) = 1 Then       // these next two check for walls
            wall_right = 1                                                              // to the right
        ElseIf character_x_position = (x + 1) And wall_data.bits(x) = 0 Then
            wall_right = 0
        EndIf
    Next
End Sub

Sub check_screen_warp()
    If character_area_x = 0 Then
        character_area_x = 30
        character_x_position = 6
        shift = 24
        board_position_x = 24
    EndIf
    If character_area_x = 31 Then
        character_area_x = 1
        character_x_position = 1
        shift = 0
        board_position_x = 0
    EndIf 
End Sub 

// Start Of Program...
OSCCON = %01111111                  // Sets the internal oscillator for 8Mhz
SetAllDigital                       // Make all Pins digital I/O's
TRISD = %00000000                   // Make all PORTB pins outputs (even though we only need PORTB, 0)
TRISB = %00000000
TRISA = %11111111
TRISC = %00000000

character_x_position = 1
character_y = 1
green_cathodes = %11111111
red_cathodes = %11111111
current_graphic_byte = 0
old_graphic_byte = current_graphic_byte
frame_counter = 20
button_debounce = 20
car_data = %00001000
game_over = 0
shift = 0
wall_flags = 0

board_position_x = 0
board_position_y = 0
character_area_x = 1
character_area_y = 1
enemy_1_area_x = 24
enemy_1_area_y = 16

// Main Loop
While True()                        // This creates an infinite loop
    draw_graphics
    update_character
    update_enemy_x
    update_enemy_y
    check_buttons
    debounce_buttons
    check_for_walls
    enemy_delay_time
    check_screen_warp
Wend                                  // Loop back to the while loop as long as we havent finished.
Attachments
pacman_animation.gif
pacman_animation.gif (1.83 MiB) Viewed 22466 times

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Post by brad » Tue Aug 03, 2010 10:11 pm

I have done quite an overhaul to the PACMAN code.

I have worked out a far better way of drawing the graphics. I actually use the OR function to setup the data within the RED GREEN and BLUE registers. once they all have their data, I send it to the LED's and it lights up one column at a time.

I have also included five bad guys who all move randomly around the game zone. All enemies detect walls and move around accordingly, there is also wall detection for PACMAN so he can't go through walls.

i am also now using an RGB display rather than the old RG display. which allows me to have more characters on the screen in different colours.

I still need to implement the pellets to munch, more levels, lives, score counter and collision detection for when the bad guys get you.

So, having said all that. Here is my revised code.

Code: Select all

Device = 18F4685         // Tell the compiler what chip we are using
Clock = 8                // Tell the compiler what we will be setting the clock to (Mhz)           
Config OSC = IRCIO67     // This tells the microcontroller to use the internal clock 

Include "RandGen.bas"
Include "utils.bas"      // we are including an extra file here which allows us to use shortcuts
                         // like "SetAllDigital" Which will take care of making all ports digital ports.                      

Const graphic_data(32) As LongWord =
(%11111111111111111111111111111111
,%10000000000001111110000000000001
,%10111101111101111110111110111101
,%10111101111101111110111110111101
,%10111101111101111110111110111101
,%10000000000000000000000000000001
,%10111101110111111111101110111101
,%10111101110111111111101110111101
,%10000001110000111100001110000001
,%11111101111110111101111110111111
,%00000101111110111101111110100000
,%00000101110000000000001110100000
,%00000101110111111111101110100000
,%11111101110111111111101110111111
,%00000000000111111111100000000000
,%11111101110111111111101110111111
,%00000101110000000000001110100000
,%00000101110101111110101110100000
,%00000101110100001000101110100000
,%00000101110111101011101110100000
,%11111101110111101011101110111111
,%10000000000000001000000000000001
,%10111101111101101011011111011101
,%10111101111101100011011111011101
,%10001101111101110111011111010001
,%11101101111101110111011111010111
,%11100000000000000000000000000111
,%11101111011111111111111011110111
,%10001111000001111110000011110001
,%10111111111101111110111111111101
,%10000000000000000000000000000001
,%11111111111111111111111111111111)                        
Const anodes(8) As Byte = (%00000001,%00000010,%00000100,%00001000,%00010000,%00100000,%01000000,%10000000) 

// variable declaration
Dim x As Byte
Dim current_graphic_byte As Byte
Dim old_graphic_byte As Byte
Dim frame_counter As Byte
Dim button_debounce As Byte
Dim shift_register As LongWord
Dim shift As Byte
Dim character_x As Byte
Dim character_y As Byte
Dim character_x_position As Byte
Dim wall_data As Byte
Dim wall_data_above As Byte
Dim wall_data_below As Byte
Dim wall_flags As Byte
Dim wall_up As wall_flags.0
Dim wall_down As wall_flags.1
Dim wall_left As wall_flags.2
Dim wall_right As wall_flags.3

Dim board_position_x As Byte
Dim board_position_y As Byte
Dim character_area_x As Byte
Dim character_area_y As Byte

Dim enemy_area_x(5) As Byte
Dim enemy_area_y(5) As Byte
Dim enemy_direction(5) As Byte
Dim enemy_on_screen_x(5) As Byte
Dim enemy_on_screen_y(5) As Byte
Dim enemy_delay_x(5) As Byte
Dim enemy_delay_y(5) As Byte
Dim enemy_temp_0 As LongWord
Dim enemy_temp_1 As LongWord
Dim enemy_temp_2 As LongWord

Dim counter As Byte
Dim rnd_number As Byte

Dim nes_flags As Byte
Dim nes_a As nes_flags.0
Dim nes_b As nes_flags.1
Dim nes_select As nes_flags.2
Dim nes_start As nes_flags.3
Dim nes_up As nes_flags.4
Dim nes_down As nes_flags.5
Dim nes_left As nes_flags.6
Dim nes_right As nes_flags.7

Dim green_data As Byte
Dim red_data As Byte
Dim blue_data As Byte 

// Port Setup
Dim nes_latch As PORTA.0
Dim nes_clock As PORTA.1
Dim nes_data As PORTA.2

Dim common_anodes As PORTB
Dim blue_cathodes As PORTC
Dim red_cathodes As PORTD

// Sub Routines

Sub draw_graphics()
    For x = 0 To 7    
        red_data = %00000000     // clear all data before we look at copying in the relevant data
        green_data = %00000000
        blue_data = %00000000
        Inc(counter)
        shift_register = graphic_data(current_graphic_byte)
        WREG = shift         // need to load our wreg with the shift data otherwise it gets corrupted when using it in the next line
        shift_register = shift_register >> (WREG)        // i am not sure why thi happens, but it does!  
        blue_data = blue_data Or shift_register  // we now have the wall data in our blue register
        If x = character_y Then
            wall_data = shift_register                  // once we have found what data is in the same row as us, save it for later.
            green_data = green_data Or character_x
        ElseIf x = character_y + 1 Then
            wall_data_above = shift_register
        ElseIf x = character_y - 1 Then
            wall_data_below = shift_register            
        EndIf
        
        If x = enemy_on_screen_y(0) And enemy_on_screen_x(0) < 8 Then
            red_data.bits(enemy_on_screen_x(0)) = 1    
        EndIf
        If x = enemy_on_screen_y(1) And enemy_on_screen_x(1) < 8 Then
            red_data.bits(enemy_on_screen_x(1)) = 1
            green_data.bits(enemy_on_screen_x(1)) = 1    
        EndIf
        If x = enemy_on_screen_y(2) And enemy_on_screen_x(2) < 8 Then
            red_data.bits(enemy_on_screen_x(2)) = 1
            green_data.bits(enemy_on_screen_x(2)) = 1
            blue_data.bits(enemy_on_screen_x(2)) = 1    
        EndIf
        If x = enemy_on_screen_y(3) And enemy_on_screen_x(3) < 8 Then
            red_data.bits(enemy_on_screen_x(3)) = 1
            blue_data.bits(enemy_on_screen_x(3)) = 1    
        EndIf
        If x = enemy_on_screen_y(4) And enemy_on_screen_x(4) < 8 Then
            green_data.bits(enemy_on_screen_x(4)) = 1
            blue_data.bits(enemy_on_screen_x(4)) = 1    
        EndIf
        
        red_data = red_data Xor %11111111   // invert all colour data because we are using common cathodes
        blue_data = blue_data Xor %11111111
        green_data = green_data Xor %11111111
        blue_cathodes = blue_data 
        red_cathodes = green_data  // first send the green data to the green latch via red_cathode port
        PORTA.bits(3) = 1
        PORTA.bits(3) = 0
        red_cathodes = red_data
        common_anodes = anodes(x)    // and now finally, the LEDs are turned on!
        DelayMS(1)
        common_anodes = %00000000       // now turn off the anodes so that the screen is blanked
        Inc(current_graphic_byte)
        If x = 7 Then                                            // reset back to the first column in this frame
            current_graphic_byte = old_graphic_byte
        EndIf
    Next          
End Sub 

Sub update_enemy()
    For x = 0 To 4
        enemy_temp_0 = graphic_data(enemy_area_y(x) + 1)
        enemy_temp_1 = graphic_data(enemy_area_y(x) - 1)    
        enemy_temp_2 = graphic_data(enemy_area_y(x))
        If enemy_direction(x) = %00000001 And enemy_delay_y(x) = 0 Then
            If rnd_number >= 0 And rnd_number <= 85 Then                             // going up
                If enemy_temp_2.bits(enemy_area_x(x) + 1) = 0  Then
                    enemy_direction(x) = %00000100
                EndIf
            ElseIf rnd_number >= 86 And rnd_number <= 171 Then
                If enemy_temp_2.bits(enemy_area_x(x) - 1) = 0 Then
                    enemy_direction(x) = %00001000
                EndIf
            EndIf
        EndIf
        If enemy_direction(x) = %00000010 And enemy_delay_y(x) = 0 Then                             // going down
            If rnd_number >= 0 And rnd_number <= 85 Then 
                If enemy_temp_2.bits(enemy_area_x(x) - 1) = 0  Then
                    enemy_direction(x) = %00001000
                EndIf
            ElseIf rnd_number >= 86 And rnd_number <= 171 Then
                If enemy_temp_2.bits(enemy_area_x(x) + 1) = 0 Then
                    enemy_direction(x) = %00000100
                EndIf
            EndIf
        EndIf
        
        If enemy_direction(x) = %00000100 And enemy_delay_x(x) = 0 Then
            If rnd_number >= 0 And rnd_number <= 85 Then 
                If enemy_temp_0.bits(enemy_area_x(x)) = 0 Then
                    enemy_direction(x) = %00000001
                EndIf
            ElseIf rnd_number >= 86 And rnd_number <= 171 Then
                If enemy_temp_1.bits(enemy_area_x(x)) = 0 Then
                    enemy_direction(x) = %00000010
                EndIf
            EndIf
        EndIf
        If enemy_direction(x) = %00001000 And enemy_delay_x(x) = 0 Then
            If rnd_number >= 0 And rnd_number <= 85 Then 
                If enemy_temp_1.bits(enemy_area_x(x)) = 0 Then
                    enemy_direction(x) = %00000010
                EndIf
            ElseIf rnd_number >= 86 And rnd_number <= 171 Then
                If enemy_temp_0.bits(enemy_area_x(x)) = 0 Then
                    enemy_direction(x) = %00000001
                EndIf
            EndIf
        EndIf
        enemy_on_screen_y(x) = enemy_area_y(x) - board_position_y
        If enemy_direction(x) = %00000001 And enemy_delay_y(x) = 0 And enemy_temp_0.bits(enemy_area_x(x)) = 0 Then    
            Inc(enemy_area_y(x))
            enemy_delay_y(x) = 20
        EndIf
        If enemy_direction(x) = %00000010 And enemy_delay_y(x) = 0 And enemy_temp_1.bits(enemy_area_x(x)) = 0 Then
            Dec(enemy_area_y(x))
            enemy_delay_y(x) = 20
        EndIf
        enemy_on_screen_x(x) = enemy_area_x(x) - board_position_x
        If enemy_direction(x) = %00000100 And enemy_delay_x(x) = 0 And enemy_temp_2.bits(enemy_area_x(x) + 1) = 0 Then
            Inc(enemy_area_x(x))
            enemy_delay_x(x) = 20
        ElseIf enemy_direction(x) = %00001000 And enemy_delay_x(x) = 0 And enemy_temp_2.bits(enemy_area_x(x) - 1) = 0 Then
            Dec(enemy_area_x(x))
            enemy_delay_x(x) = 20
        EndIf
    Next
End Sub

Sub enemy_delay_time()
    For x = 0 To 4
        If enemy_delay_x(x) <> 0 Then
            Dec(enemy_delay_x(x))
        EndIf
        If enemy_delay_y(x) <> 0 Then
            Dec(enemy_delay_y(x))
        EndIf
    Next
End Sub

Sub check_control_pad()
    nes_latch = 1      // grab the state of the buttons
    nes_latch = 0      // by giving a positive edge to the latch enable
    For x = 0 To 7
        nes_flags.bits(x) = nes_data    // the first bit (button a) will be shown on the nes_data pin, we read it, then clock through
        nes_clock = 1                   // the remaining 7 bits to check the state of all buttons.
        nes_clock = 0
    Next   
End Sub

Sub check_buttons()
    If button_debounce = 0 Then
        rnd_number = counter
    EndIf
    If button_debounce = 0 And nes_left = 0 And character_x_position < 3 And shift = 0 And wall_left = 0 Then
        Inc(character_x_position)
        Inc(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_left = 0 And character_x_position > 3 And shift < 24 And shift > 0 And wall_left = 0 Then
        Inc(shift)
        Inc(board_position_x)
        Inc(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_left = 0 And shift = 24 And character_x_position > 2  And character_x_position < 7 And wall_left = 0 Then
        Inc(character_x_position)
        Inc(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_left = 0 And character_x_position = 3 And shift <> 24 And wall_left = 0 Then
        Inc(shift)
        Inc(board_position_x)
        Inc(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_left = 0 And character_x_position = 4 And shift <> 24 And wall_left = 0 Then
        Inc(shift)
        Inc(board_position_x)
        Inc(character_area_x)
        button_debounce = 15
    EndIf
    
    If button_debounce = 0 And nes_right = 0 And character_x_position > 4 And shift = 24 And wall_right = 0 Then
        Dec(character_x_position)
        Dec(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_right = 0 And character_x_position < 4 And shift < 24 And shift > 0 And wall_right = 0 Then
        Dec(shift)
        Dec(board_position_x)
        Dec(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_right = 0 And shift = 0 And character_x_position < 5 And character_x_position > 0 And wall_right = 0 Then
        Dec(character_x_position)
        Dec(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_right = 0 And character_x_position = 4 And shift <> 0 And wall_right = 0 Then
        Dec(shift)
        Dec(board_position_x)
        Dec(character_area_x)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_right = 0 And character_x_position = 3 And shift <> 0 And wall_right = 0 Then
        Dec(shift)
        Dec(board_position_x)
        Dec(character_area_x)
        button_debounce = 15
    EndIf     
    
    If button_debounce = 0 And nes_up = 0 And character_y < 3 And current_graphic_byte = 0 And wall_up = 0 Then
        Inc(character_y)
        Inc(character_area_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_up = 0 And character_y > 3 And current_graphic_byte < 24 And current_graphic_byte > 0 And wall_up = 0 Then
        Inc(current_graphic_byte)
        Inc(old_graphic_byte)
        Inc(character_area_y)
        Inc(board_position_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_up = 0 And current_graphic_byte = 24 And character_y > 2  And character_y < 6 And wall_up = 0 Then
        Inc(character_y)
        Inc(character_area_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_up = 0 And character_y = 3 And current_graphic_byte <> 24 And wall_up = 0 Then
        Inc(current_graphic_byte)
        Inc(old_graphic_byte)
        Inc(character_area_y)
        Inc(board_position_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_up = 0 And character_y = 4 And current_graphic_byte <> 24 And wall_up = 0 Then
        Inc(current_graphic_byte)
        Inc(old_graphic_byte)
        Inc(character_area_y)
        Inc(board_position_y)
        button_debounce = 15
    EndIf
    
    If button_debounce = 0 And nes_down = 0 And character_y > 4 And current_graphic_byte = 24 And wall_down = 0 Then
        Dec(character_y)
        Dec(character_area_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_down = 0 And character_y < 4 And current_graphic_byte < 24 And current_graphic_byte > 0 And wall_down = 0 Then
        Dec(current_graphic_byte)
        Dec(old_graphic_byte)
        Dec(character_area_y)
        Dec(board_position_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_down = 0 And current_graphic_byte = 0 And character_y < 5  And character_y > 1 And wall_down = 0 Then
        Dec(character_y)
        Dec(character_area_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_down = 0 And character_y = 4 And current_graphic_byte <> 0 And wall_down = 0 Then
        Dec(current_graphic_byte)
        Dec(old_graphic_byte)
        Dec(character_area_y)
        Dec(board_position_y)
        button_debounce = 15
    ElseIf button_debounce = 0 And nes_down = 0 And character_y = 3 And current_graphic_byte <> 0 And wall_down = 0 Then
        Dec(current_graphic_byte)
        Dec(old_graphic_byte)
        Dec(character_area_y)
        Dec(board_position_y)
        button_debounce = 15
    EndIf             
End Sub

Sub debounce_buttons()
    If button_debounce <> 0 Then
        Dec(button_debounce)
    EndIf
End Sub

Sub update_character()
    character_x = %00000000   // first of all we need to clear our characters last position and then
    character_x.bits(character_x_position) = 1     // send in the new position (otherwise we get multiple characters on the screen
End Sub

Sub check_for_walls()
    For x = 0 To 7 
        If character_x_position = x Then
            If wall_data_above.bits(x) = 1 Then
                wall_up = 1
            ElseIf wall_data_above.bits(x) = 0 Then
                wall_up = 0
            EndIf
            If wall_data_below.bits(x) = 1 Then
                wall_down = 1
            ElseIf wall_data_below.bits(x) = 0 Then
                wall_down = 0
            EndIf
        EndIf
    Next
                    
    For x = 0 To 6
        If character_x_position = (x) And wall_data.bits(x + 1) = 1 Then           // these first two check for
            wall_left = 1                                                               // walls to the left
        ElseIf character_x_position = (x) And wall_data.bits(x + 1) = 0 Then                                              
            wall_left = 0
        ElseIf character_x_position = (x + 1) And wall_data.bits(x) = 1 Then       // these next two check for walls
            wall_right = 1                                                              // to the right
        ElseIf character_x_position = (x + 1) And wall_data.bits(x) = 0 Then
            wall_right = 0
        EndIf
    Next
End Sub

Sub check_screen_warp()
    If character_area_x = 0 Then
        character_area_x = 30
        character_x_position = 6
        shift = 24
        board_position_x = 24
    EndIf
    If character_area_x = 31 Then
        character_area_x = 1
        character_x_position = 1
        shift = 0
        board_position_x = 0
    EndIf 
End Sub 

// Start Of Program...
OSCCON = %01111111                  // Sets the internal oscillator for 8Mhz
SetAllDigital                       // Make all Pins digital I/O's
TRISD = %00000000                   // Make all PORTB pins outputs (even though we only need PORTB, 0)
TRISB = %00000000
TRISA = %11110100                   // latch and clock are outputs. Data is an input, bit 3 is 74373 latch enable
TRISC = %00000000

character_x_position = 1
character_y = 1
blue_cathodes = %11111111
red_cathodes = %11111111
current_graphic_byte = 0
old_graphic_byte = current_graphic_byte
frame_counter = 20
button_debounce = 20
car_data = %00001000
game_over = 0
shift = 0
wall_flags = 0

board_position_x = 0
board_position_y = 0
character_area_x = 1
character_area_y = 1

enemy_area_y(0) = 30
enemy_area_x(0) = 30
enemy_area_y(1) = 30
enemy_area_x(1) = 15
enemy_area_y(2) = 30
enemy_area_x(2) = 1
enemy_area_y(3) = 14
enemy_area_x(3) = 21
enemy_area_y(4) = 1
enemy_area_x(4) = 30
enemy_direction(0) = %00000001
enemy_direction(1) = %00000001
enemy_direction(2) = %00000001
enemy_direction(3) = %00000001
enemy_direction(4) = %00000001

nes_latch = 0
nes_clock = 0

// Main Loop
While True()                        // This creates an infinite loop
    draw_graphics
    update_character
    update_enemy
    enemy_delay_time
    check_control_pad
    check_buttons
    debounce_buttons
    check_for_walls
    check_screen_warp
Wend                                  // Loop back to the while loop as long as we havent finished. 


Last edited by brad on Sun Aug 08, 2010 9:58 pm, edited 2 times in total.

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Sun Aug 08, 2010 7:52 am

Yeah I like it, its looking pretty good Brad. :)

It would be good if we could use PWM some how on this little 8x8 matrix.

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Post by brad » Sun Aug 08, 2010 9:58 pm

bitfogav wrote:Yeah I like it, its looking pretty good Brad. :)

It would be good if we could use PWM some how on this little 8x8 matrix.
PWM would be a nice step forward, it would ensure loads more colours :)

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Sat Aug 14, 2010 3:32 am

I just looked at the detials of the microchips that you are using

Image

That is alot of program memory and RAM :)
Attachments
ram.jpg
ram.jpg (36.37 KiB) Viewed 22412 times

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Post by brad » Sat Aug 14, 2010 9:54 pm

Yeah, plenty for just about any use really :)

I have now added an lcd display to my pacman game and will (maybe soon?) get around to programming it in to show you your lives, points, level etc...

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Sat Aug 14, 2010 9:58 pm

brad wrote:Yeah, plenty for just about any use really :)

I have now added an lcd display to my pacman game and will (maybe soon?) get around to programming it in to show you your lives, points, level etc...
Brad you do come up with some great idea :)

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Post by brad » Sat Aug 14, 2010 10:02 pm

Thanks buddy, it's just a really easy way of showing you what is going on, rather than having scrolling text across the 8x8 matrix.

The LCD displays are so cheap - $4 from ebay :)

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Sun Aug 15, 2010 8:04 pm

So on your RGB version of the Pac Man game, you are using the NES control pad for you controls? and how are you controlling the register data, are you using 74343 to shift all your data to the RGB display, Or are you just using one PORT = for blue
and one PORT = for RED etc?

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Post by brad » Sun Aug 15, 2010 9:24 pm

bitfogav wrote:So on your RGB version of the Pac Man game, you are using the NES control pad for you controls? and how are you controlling the register data, are you using 74343 to shift all your data to the RGB display, Or are you just using one PORT = for blue
and one PORT = for RED etc?
I was waiting for this question :) I have come up with a little bit of a sly way of making this work. There are not enough port pins to cover the common anodes, then red green and blue cathodes. So I have used one port for the anodes, one port for blue and then one port is shared between being directly connected to the red cathodes and then it also indirectly connects to the green cathodes via a single 74373.

Have a look at this code:

Code: Select all

        blue_cathodes = blue_data
        red_cathodes = green_data  // first send the green data to the green latch via red_cathode port
        PORTA.bits(3) = 1
        PORTA.bits(3) = 0
        red_cathodes = red_data
        common_anodes = anodes(x)    // and now finally, the LEDs are turned on!
        DelayMS(1) 
When I draw one line of graphics, I send the blue data to the blue cathodes, then the green data to the port where both red cathodes and the green 74373 are connected to, I save this to the green 74373 by sending a pulse to the 74373 latch, I then send the red data to the same place but I don't latch the green 74373 (obviously) and then finally, in order for the LED's to turn on, I need to send out my data to the common anodes.

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Sun Aug 15, 2010 9:29 pm

Yeah I see how its works now, I looked at this bit of code and was thinking what is going on here :)

Code: Select all

        blue_cathodes = blue_data 
        red_cathodes = green_data  // first send the green data to the green latch via red_cathode port 
        PORTA.bits(3) = 1 
        PORTA.bits(3) = 0 
        red_cathodes = red_data 
        common_anodes = anodes(x)    // and now finally, the LEDs are turned on! 
        DelayMS(1) 
thanks for explaining Brad

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Post by brad » Sun Aug 15, 2010 9:38 pm

bitfogav wrote:Yeah I see how its works now, I looked at this bit of code and was thinking what is going on here :)

Code: Select all

        blue_cathodes = blue_data 
        red_cathodes = green_data  // first send the green data to the green latch via red_cathode port 
        PORTA.bits(3) = 1 
        PORTA.bits(3) = 0 
        red_cathodes = red_data 
        common_anodes = anodes(x)    // and now finally, the LEDs are turned on! 
        DelayMS(1) 
thanks for explaining Brad
Hey, that's what i'm here for!

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Post by brad » Mon Aug 16, 2010 9:46 pm

Just an update:

I managed to spend a little bit of time tonight working on this game (for the first time in about two weeks!)

I now have the RGB matrix all working with a NES control pad and a 16 x 2 LCD screen and all up it only uses two chips!

I'll post more details soon...

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Post by bitfogav » Mon Aug 16, 2010 9:48 pm

brad wrote:Just an update:

I managed to spend a little bit of time tonight working on this game (for the first time in about two weeks!)

I now have the RGB matrix all working with a NES control pad and a 16 x 2 LCD screen and all up it only uses two chips!

I'll post more details soon...
Be nice to see some pictures or a video when you've got to that point buddy :)

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Post by brad » Tue Aug 17, 2010 10:01 pm

Coming soon!

Really I promise... maybe... :)

Post Reply
[phpBB Debug] PHP Warning: in file [ROOT]/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1266: count(): Parameter must be an array or an object that implements Countable

Who is online

Users browsing this forum: No registered users and 2 guests