Main > Project Announcements
Vectorising an arcade game: VectorKong is Completed
<< < (5/11) > >>
bobbyb13:
Cooler by the minute!
I'm still awestruck at this kind of work.

Absolutely brilliant.
10yard:

--- Quote from: bobbyb13 on April 22, 2022, 12:27:59 am ---Cooler by the minute!
I'm still awestruck at this kind of work.

Absolutely brilliant.

--- End quote ---

Thank you!
10yard:
In this part 3a,  I'm going to be adding vector sprites for Oilcan Flames, Fireballs, Barrels, Pauline and Paulines Love Heart.  I've also introduced colour.



First thing to report is my graphics optimisation resulting in a significant increase to the vectors that can be drawn per frame.
I was able to triple the limit - to 3000 vectors per frame*.  We're not going to get anywhere near those numbers.
* Tested with MAME version 0.243 running fullscreen opengl video.

I was able to programmatically clear the roms sprite banks during startup.  There is an overhead for MAME to draw stuff and we won't need the games original pixel graphics at all.  My previous hack was just to hide them in the background.  This is a much better solution.


--- Code: ---function clear_graphic_banks()
-- clear the contents of the DK graphics banks 1 and 2
local _bank1, _bank2 = bnk.regions[":gfx1"], bnk.regions[":gfx2"]
if _bank1 and _bank2 then
for _addr=0, 0xfff do _bank1:write_u8(_addr, 0) end  -- clear bank 1
for _addr=0, 0x1fff do _bank2:write_u8(_addr, 0) end  -- clear bank 2
end
end

--- End code ---


So back to the main focus of this update.  I made progress with drawing and animating sprites.

I made vectors versions of the needed sprites and added them to my program's vector library.  I used a paint program to draw lines and to experiment with how things would look e.g.



I added flames to the oilcan first as I thought that would be fairly simple.  The flames ignite after the first blue barrel strikes the oilcan.  I check the flame (memory location 0x6a29) is active (value is between 0x40 and 0x43) and then draw flames as vectors in yellow and red.  The red flame extends upwards in a simple random animation.


--- Code: ---function draw_oilcan_and_flames(y, x)
draw_object("oilcan",  y, x)
local _sprite = read(0x6a29)
if _sprite >= 0x40 and _sprite <= 0x43 then  -- oilcan is on fire
draw_object("flames", y+16, x, YEL)  -- base of flames
draw_object("flames", y+16+math.random(0,3), x, RED)  -- flames extend upwards
end
end

--- End code ---

Fireballs were taxing.  There are 6 fireball slots in RAM.  Each fireball has 32 bytes of data including status (active/inactive), current x/y position, colour and direction of movement.  I check each fireball slot every frame looking for active fireballs,  I draw active fireballs in 3 parts:  The body in yellow,  the flames extending upwards in red and the eyes in red.  The flames were given a simple animation similar to the oilcan flame effect.  If the fireball changes direction then I flip the fireball vectors so they are mirrored when drawn.






--- Code: ---function draw_fireballs()
local _y, _x
for _i, _addr in ipairs(FIREBALLS) do
if read(_addr, 1) then  -- fireball is active
_y, _x = 247 - read(_addr+5), read(_addr+3) - 22
if read(_addr+0xd, 1) then
vector_flip = 13  -- fireball is moving right so flip the vectors
end
draw_object("fire-1", _y, _x, YEL) -- draw body
draw_object("fire-2", _y+math.random(0,3), _x, RED)  -- draw flames extending upwards
draw_object("fire-3", _y+1, _x, RED)  -- draw eyes
vector_flip = 0
end
end
end

--- End code ---

Here's the Oilcan with flames throwing out a fireball.





Barrels were even more taxing than fireballs.  There are 8 barrel slots in RAM.  Similar to fireballs,  each barrel has 32 bytes of corresponding data.  The data comprises of status (inactive/being deployed/rolling), color indicator (normal or blue), crazy barrel indicator, movement direction, current x/y position and a bunch of other stuff. 

If the barrel is crazy/wild or going down a ladder then I draw a longer sideways barrel.  These can be blue or brown.





otherwise I draw a circular rolling barrel.  These can also be blue or brown.





Here's my function for handling the barrels and their rolling animation.


--- Code: ---function draw_barrels()
local _y, _x, _type, _state
for _i, _addr in ipairs(BARRELS) do
if read(_addr) > 0 and read(0x6200, 1) and read(_addr+3) > 0 then  -- barrel active and Jumpman alive
_y, _x = 251 - read(_addr+5), read(_addr+3) - 20
_type = read(_addr+0x15) + 1  -- type of barrel: 1 is normal, 2 is blue/skull

if read(_addr+1, 1) or bits(read(_addr+2))[1] == 1 then  -- barrel is crazy or going down a ladder
_state = read(_addr+0xf)
draw_object("down", _y, _x-2, ({BRN, CYN})[_type])
draw_object("down-"..tostring(_state % 2 + 1), _y, _x - 2, ({LBR, BLU})[_type])
else  -- barrel is rolling
_state = barrel_state[_addr] or 0
if scr:frame_number() % 10 == 0 then
if read(_addr+2, 2) then _state = _state - 1 else _state = _state+1 end  -- roll left or right?
barrel_state[_addr] = _state
end
draw_object("roll", _y, _x, ({BRN, CYN})[_type])
draw_object(({"roll-", "skull-"})[_type]..tostring(_state % 4 + 1), _y, _x,({LBR, BLU})[_type])
end
end
end
end

--- End code ---

I made a simple vector representation of Pauline and her love heart/broken heart.
This function check for Paulines animation state.  The original DK uses several sprites for Pauline as she rocks back and forth.  I made her Jump up instead to keep the effect simple.


--- Code: ---function draw_pauline()
local _y, _x = 235 - read(0x6903), 90
if read(0x6905) ~= 17 and read(0x6a20, 0) then _y = _y + 3 end  -- Pauline jumps when heart not showing
draw_object("paul-1", _y, _x, MAG)
draw_object("paul-2", _y, _x, PNK)
end

--- End code ---

This function reads the status of the love heart (full or broken) and position prior to drawing.


--- Code: --- function draw_loveheart()
_y, _x = 250 - read(0x6a23), read(0x6a20) - 23
if _x > 0 then draw_object(read(0x6a21) + 0xf00, _y, _x, MAG) end
end

--- End code ---





Lastly,  I made bonus points appear when jumping or smashing barrels.  I adjusted the y position so bonus points don’t overlap with the girders.


--- Code: ---function draw_points()
-- draw 100, 300, 500 or 800 when points awarded
if read(0x6a30) > 0 then
_y, _x = 254 - read(0x6a33), read(0x6a30) - 22
draw_object(read(0x6a31) + 0xf00, _y+3, _x, YEL)  -- move points up a little so they don't overlap as much
end
end

--- End code ---



The hammer smashing animation still needs to be done,  along with other sprites for Jumpman and Donkey Kong.  They should be in the next part.

Here's a gameplay video showing my progress so far (without hammer smashing).   I've used a simple box to represent Jumpman's position on screen.  Hey,  it's almost playable like this.

nitrogen_widget:
this is looking really cool.
10yard:

--- Quote from: nitrogen_widget on May 05, 2022, 06:54:36 pm ---this is looking really cool.

--- End quote ---

Thanks!  It's all coming together nicely. 

This project is more work than I was expecting but that's typical.  I'm enjoying the journey.

Working on Kong at the mo.  It's hard to get the familiarity without overdoing the vectors.  He's looking grumpier  :lol.

Navigation
Message Index
Next page
Previous page

Go to full version