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.

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.