Large gameboard drawing ideas for the Vic-20 (or other compact memory unit)

Discussion, Reviews & High-scores

Moderator: Moderators

Post Reply
Kakemoms
Vic 20 Nerd
Posts: 740
Joined: Sun Feb 15, 2015 8:45 am

Large gameboard drawing ideas for the Vic-20 (or other compact memory unit)

Post by Kakemoms »

The posted preview of Realms of Quest gave me some ideas of how to get a large gameboard without having to store each tile in memory. I then made a short (and buggy) basic program to show the principle:

Code: Select all

5 addr=40960
6 print"testmap start:";addr
7 print"(g)generate or (p)plot?": input c$
8 if c$="p" then goto 250
10 dim sx(255),sy(255)
20 print"how large map?"
30 input a
40 print"map will be";a;"x";a;"squares."
45 print"seed"
48 input sd
50 print"max line width?"
55 input w
60 print"number of lines";:input nl
65 bpl=int(a/8)+3
70 print "max";bpl;"bytes per line"
75 poke addr,bpl: addr=addr+1
78 poke addr,w: addr=addr+1
80 print "bleed width (0=none)?"
90 input bw
95 poke addr,bw: addr=addr+1
96 poke addr,nl: addr=addr+1
100 for t=1tow
110 print"generating";t;"wide lines"
115 for u=1tonl
120 sx(t)=int(a*rnd(a*sd))
125 poke addr,sx(t): addr=addr+1
130 sy(t)=int(a*rnd(a*sd))
135 poke addr,sx(t): addr=addr+1
140 print"start";sx(t);",";sy(t)
145 bf=1: lin=0
150 for v=1toa
155 lr=(int(rnd(v*t*sd)+0.5)*bf)
158 lin=lin+lr
160 bf=bf*2
165 if int((v)/8)<>int((v-1)/8) then poke addr,lin: addr=addr+1: lin=0: bf=1
180 next v
185 if int((v)/8)=int((v-1)/8) then poke addr,lin: addr=addr+1
190 print "addr";addr
196 next u
200 next t
210 poke addr,255
250 print "data generated" 
300 print "plot start (x,y)?"
310 input xps,yps
315 w=peek(40961): bw=peek(40962): nl=peek(40963)
320 for t=4096 to 4096+506
330 poke t, 48: poke 33792+t,0
340 next t
350 se=peek(40960)
360 a=40964
370 sx=peek(a):sy=peek(a+1):a=a+2
375 pk=0
380 if(sx>xps)and(sx<(xps+22))and(sy>yps)and(sy<(yps+20))then pk=4096+(sx-xps)+((sy-yps)*22):pOpk,(pE(pk)+1)
385 if pk<>0 then for v=-bw to bw: pOpk+v,(pE(pk+v)+1):next v
390 for t=1 to (se-2)
400 dc=peek(a+t-1):bf=1
410 for u=0to7
415 sx=sx+1
420 if (int(dc/2)*2)<>dc then dc=dc-1: sx=sx-2
430 dc=dc/2
440 sy=sy+1
441 pk=0
442 if(sx>xps)and(sx<(xps+22))and(sy>yps)and(sy<(yps+20))then pk=4096+(sx-xps)+((sy-yps)*22):pOpk,(pE(pk)+1)
443 if pk<>0 then for v=-bw to bw: pOpk+v,(pE(pk+v)+1):next v
444 rem print u;t;sx;sy
445 next u,t
446 a=a+se-2
450 nl=nl-1: if nl>0 then goto 370 
Basically it builds a table of lines that are as long as the game board. Each line has a starting point on the board and is bit-coded. It is drawn from a low y-coordinate towards the maximum y-coordinate of the board (or a limited length if you want to). A 0-bit means that the line is shifted to the left while a 1-bit means that the line is shifted to the right. The "bleed function" means that the line is drawn at height 2 and there is a width around it that is drawn at height 1. Drawing two lines over each other means that height increases more.. and so on.

There are a number of ways to "bleed" the lines and/or to connect the line points. You can even have line functions that are loosely guided on the bit pattern. Anyway, the meaning is to get reproducible result that defines a map that can be scrolled around. For example a 100x100 map defined from 100 lines could be stored in 1500 bytes of memory (more or less).

The idea is then to use this "map" as a heightmap and draw the landscape from its basis. For example use height=0 as sea, 1-3 as different types of land and 4+ as mountains. Maybe 9+ is snow (or something). You get the idea.

Other features on the map would have to be defined in tables aswell. Roads, houses, caves and alike.
Forbidden64
Vic 20 Hobbyist
Posts: 146
Joined: Sun Feb 28, 2016 9:59 pm
Location: CA USA

Re: Large gameboard drawing ideas for the Vic-20 (or other compact memory unit)

Post by Forbidden64 »

A fascinating concept, and one I have thought about... My only problem was when you code it in one bit, you get 8x the space...but only one type of tile, either wall or no wall; tree or no tree etc.. In some "game engines" I've made in the past, I just used whole characters commonly, and then displayed a sprite depending on what character it was onto the entire screen. That was of course, in MS-DOS in VGA. On the VIC this is even easier...just make the character itself into the sprite.

If we limit ourselves to one bit maps, it just occurred to me that it could be possible to just do the trees, enemies, and such(basically objects) separately, storing those locations in a buffer as coordinates having a an array limit, current array count(for looping speed), properties of that object(stored as different arrays, with a corresponding array count). I've used this arrangement to get around basic not having objects before. For example:


Current object pointer:
ct = 0 :rem defined at loop
total number of enemies generated:
et = 1
enemy name
en$(1) = "Killer Rabbit"
enemy hits
ep(1) = 10
enemy damage per hit
eh(1) = 1
enemy location:
ex(1) = 55
ey(1) = 33

A collision check can be made by scrolling through many different objects and doing the same comparison.
So the object is expressed like this:

for i = ct to et
if x=ex(ct) and y = ey(ct) then 530: battle sequence.
next

In this way, your binary map could be used to generate a massive maze, or landscape of trees etc. and then the actual game objects could be held in small arrays, eliminating most of the memory usage. Additionally, the code for managing even a large number of enemy moves is handled with relatively little code, once the generation occurs.

I've wanted to build a "town generator" for some time, but I never gotten around to it. Each store entrance represented by a different sprite. Armorer etc. I have always done these towns manually...but to create a truly massive map, such a generator would be required, because even if you wanted them to look the same to save memory, that would still require that they are asserted in the first place(saved in that state). A random generator for towns with a seed count being the only save state would be ideal to get the exact same construct from a non-random seed count. you can see this in effect with sim city 2000 and it's seed generating system for topography.
Forbidden64
Vic 20 Hobbyist
Posts: 146
Joined: Sun Feb 28, 2016 9:59 pm
Location: CA USA

Re: Large gameboard drawing ideas for the Vic-20 (or other compact memory unit)

Post by Forbidden64 »

My plan for the game I am working on now, is to use NO memory for maps. Sounds too good to be true? Why not...just load the map directly into screen memory, then discard the variables as they are printed.



500 REM LOADMAP METHOD:
510 OPEN 1,1,0,""
520 INPUT#1,T: rem total lines on this map.
530 FORI=1toT
540 INPUT#1,MAP$
550 PRINT MAP$
560 NEXT
570 CLOSE #1
580 RETURN

On the map editor, you add an X character to mark where your start point on the map is. An E for generating each enemy object, and so on. Then you scan through the map and destroy these characters, generate the object values, and then return to the main game loop.
Ta da! Butttt....you cant use it for scrolling real time, obviously. At best you could use this engine to make a side scroller where it scrolls the whole screen.

Faerytale Adventure has the largest pixel scrolling map of any commodore game ever made, and was ported from the Amiga[for the commodore 64]. It is a pill to play though as it is constantly accessing disk to swap out map files. I'd honestly rather play this game on an Amiga any day.
Forbidden64
Vic 20 Hobbyist
Posts: 146
Joined: Sun Feb 28, 2016 9:59 pm
Location: CA USA

Re: Large gameboard drawing ideas for the Vic-20 (or other compact memory unit)

Post by Forbidden64 »

How long is the plot part of your program supposed to take?!? lol. I have it running at warp speed and have been sitting here for 5 minutes...and then it crashed :< Illegal quantity error in 400.
I'll have to try some different inputs perhaps. Much smaller ones this time.

I used inputs
100
100
4
8
0
25
25
Post Reply