NaaLaa Community

Code dump => Code battle => Topic started by: Marcus on August 31, 2016

Title: Online Gorillas / Tanks
Post by: Marcus on August 31, 2016
I doubt we'll see much response here, because the low amount of active users. But I still wanna give this a shot, try and awaken the coding warriors that exist in all of us.


Does anyone here remember the old QBASIC game Gorillas (https://en.wikipedia.org/wiki/Gorillas_(video_game) (https://en.wikipedia.org/wiki/Gorillas_(video_game)))? The most popular version of this genre today is probably WORMS. Anyhow, I thought about writing something similar, but as a two player online game. It thought of it as another example for the P2P extension. But rather than just coding it myself, I now invite everyone who's interested to give it a shot, and maybe we'll see some nice variations. The "battle" ends in two weeks, that is Wednesday September 14.

Asking for any kind of help, even code examples, in this thread is NOT a crime - au contraire!
Title: Re: Online Gorillas / Tanks
Post by: Marcus on August 31, 2016
I attached some starter code, just for showing a simple way of dealing with terrain destruction.

Probably the graphics used have some sort of copyright, but let's not go nuts here.

Edit:  Then I had a look at the original QBASIC game on youtube and realized that the gorillas most likely couldn't "fall down" as in the code I just posted. Well, c'est la vie!
Title: Re: Online Gorillas / Tanks
Post by: cvirus on August 31, 2016
Audier.dll is missing. :-)
Title: Re: Online Gorillas / Tanks
Post by: cvirus on August 31, 2016
My Gorillas are in the ground  8). It worked nice.
Title: Re: Online Gorillas / Tanks
Post by: B+ on August 31, 2016
 ;D I was very impressed with this feat of engineering.
Title: Re: Online Gorillas / Tanks
Post by: Marcus on September 01, 2016
Just some more starter code:

Code: [Select]
' Banana throwing.
set redraw off

' Forward difference gravity effect.
gravity# = 0.02

' Starting position.
startX = 64
startY = 400

' Power, should be controlled.
power# = 3.2

' Set state to 0 (aim and fire).
state = 0

do
' State 0: Aim and fire.
if state = 0
' Calculate angle.
dx = mousex() - startX
dy = mousey() - startY
if not (dx = 0 and dy = 0)
angle# = atan2(float(dy), float(dx))
endif

' Fire?
if mousebutton(0, true)
state = 1
projX# = float(startX)
projY# = float(startY)
projDX# = cos(angle)*power
projDY# = sin(angle)*power
endif

' State 1: Projectile in the air.
elseif state = 1
projX = projX + projDX
projY = projY + projDY
projDY = projDY + gravity
' Out of bounds?
if projX < 0.0 or projX >= float(width(primary)) or projY < 0.0 or projY >= float(height(primary))
state = 0
endif
endif


set color 0, 0, 0
cls
set color 255, 255, 255

set caret width(primary)/2, 8
center "Move mouse cursor to aim, click to fire!"

' State 0: Draw aim.
if state = 0
' Arrow.
endX = startX + int(int(cos(angle)*40.0))
endY = startY + int(sin(angle)*40.0)
draw line startX, startY, endX, endY
draw line endX, endY, endX + int(cos(angle - 160.0)*16.0), endY + int(sin(angle - 160.0)*16.0)
draw line endX, endY, endX + int(cos(angle + 160.0)*16.0), endY + int(sin(angle + 160.0)*16.0)

' State 1: Draw projectile.
else
k# = 1.0/sqr(projDX*projDX + projDY*projDY)
dxf# = 8.0*k*projDX
dyf# = 8.0*k*projDY
draw line int(projX - dxf), int(projY - dyf), int(projX), int(projY)
endif

redraw
wait 16
until keydown(27, true)
Title: Re: Online Gorillas / Tanks
Post by: B+ on September 02, 2016
Oh boy! I got side tracked animating Gorillas.

Also Mopz your  draw filled circle procedure is fast but it does not draw very round circles.

The last 2 procedures have both to compare in this very intense filled circle drawing program.
To compare switch the 2 in the fcirc procedure names and run the program with both procedures.

Anyway, I am pretty sure you were planning on PNG's for all this but this was my first step towards robot like animation.
I can put arms and legs at any size and angle.

Code: [Select]
' Gorilla animation.txt for Naalaa [B+=MGA] 2016-09-02

constant:
xmax = 1200
ymax = 700
GORc = 0x0f0f14
gScaleBig# = 10.0
visible:
curScale# = gScaleBig#
hidden:

set window 80, 40, xmax, ymax
set redraw false

while 1
set color 20, 128, 190
draw rect 0, 0, xmax, ymax, true
  f = f + 1
  curScale# = 1.0
  _DrawGorilla 35, 15, f % 3, f % 4
  curScale# = 2.0
  _DrawGorilla 80, 50, (f+1) % 3, f % 4
  curScale# = 4.0
  _DrawGorilla 200, 100, (f+2) % 3, f % 4
  curScale# = 6.0
  _DrawGorilla 400, 175, (f+3) % 3, f % 4
  curScale# = 8.0
  _DrawGorilla 650, 200, (f+4) % 3, f % 4
  curScale# = 10.0
  _DrawGorilla 950, 250, (f+5) % 3, f % 4
redraw
  wait 1000
wend

procedure drawAppendage(x, y, r, lng, Ang, r2, lng2, Ang2, r3, lng3, Ang3)
 
set colori 0x0d0d11

  fx# = float(x)
fy# = float(y)
flng# = float(lng)
flng2# = float(lng2)
flng3# = float(lng3)
fAng# =float(Ang)
  fAng2# =float(Ang2)
fAng3# =float(Ang3)


  xe# = fx# + flng# * cos(fAng#)
  ye# = fy# + flng# * sin(fAng#)
  dx# = (xe# - fx#) / flng#
  dy# = (ye# - fy#) / flng#
  for i = 0 to lng
    cx# = fx# + float(i) * dx#
    cy# = fy# + float(i) * dy#
    _fcirc int(cx#), int(cy#), r
  next
  'color 11 dev/debug
  x1# = cx#
  y1# = cy#
  xe# = x1# + flng2# * cos(fAng2#)
  ye# = y1# + flng2# * sin(fAng2#)
  dx# = (xe# - x1#) / flng2#
  dy# = (ye# - y1#) / flng2#
  for i = 0 to lng2
    cx# = x1# + float(i) * dx#
    cy# = y1# + float(i) * dy#
    _fcirc int(cx#), int(cy#), r2
  next
  'color 14 dev/debug
  x1# = cx#
  y1# = cy#
  xe# = x1# + flng3# * cos(fAng3#)
  ye# = y1# + flng3# * sin(fAng3#)
  dx# = (xe# - x1#) / flng3#
  dy# = (ye# - y1#) / flng3#
  for i = 0 to lng3
    cx# = x1# + float(i) * dx#
    cy# = y1# + float(i) * dy#
    _fcirc int(cx#), int(cy#), r3
  next

endproc

procedure DrawGorilla(x, y, arms, legs)
  set colori GORc
  darker = 0x050505
  belly = 0x121216

  'draw head and body
' top center
  _fcirc x, y + scl(2.0), scl(3.0)
'left ear/neck           
  _fcirc x - scl(0.6), y + scl(4.2), scl(3.0) 
'right ear/neck
  _fcirc x + scl(0.6), y + scl(4.2), scl(3.0) 
'l sh
  _fcirc x - scl(5.7), y + scl(8.2), scl(3.1) 
'r sh
  _fcirc x + scl(5.7), y + scl(8.2), scl(3.1) 

'upper chest
  _fcirc x, y + scl(12.0), scl(8.0)
'hips             
  _fcirc x - scl(3.0), y + scl(22.0), scl(4.0)
'hips
  _fcirc x + scl(3.0), y + scl(22.0), scl(4.0)

'belly part one
  _fcirc x, y + scl(18.0), scl(6.0) 
'belly
set colori belly
  _fcirc x, y + scl(18.0), scl(4.0)

set color 60,60,60
'l eye socket
  _fcirc x + scl(-0.75), y + scl(2.0), scl(1.0)
'r eye socket
  _fcirc x + scl(0.75), y + scl(2.0), scl(1.0)
'l nostril
  _fcirc x + scl(-0.5), y + scl(3.8), scl(0.6)
'r nostril
  _fcirc x + scl(0.5), y + scl(3.8), scl(0.6)   

set colori darker
'l eye socket 
  _fcirc x + scl(-0.75), y + scl(2.4), scl(0.7)
'r eye socket
  _fcirc x + scl(0.75), y + scl(2.4), scl(0.7)

set colori 0x0
'dark eye area 
  draw rect x - scl(0.5), y + scl(1.9), scl(1.0), scl(1.0), true
'2 notrils and mouth
  _fcirc x + scl(-0.55), y + scl(4.0), scl(0.4)
  _fcirc x + scl(0.55), y + scl(4.0), scl(0.4)
draw rect x - scl(0.8), y + scl(5.2), scl(1.6), scl(0.2), true

set colori 0xffffff
'whites of reflected in eyes
  _fcirc x + scl(-0.80), y + scl(2.2), scl(0.2)
  _fcirc x + scl(0.80), y + scl(2.2), scl(0.2)

'appendages set their own color
  '  legs
if legs = 0
  _drawAppendage x + scl(5.0), y + scl(24.0), scl(3.0), scl(3.0), 45, scl(3.0), scl(8.0), 90, scl(2.5), scl(2.0), 101
  _drawAppendage x - scl(5.0), y + scl(24.0), scl(3.0), scl(3.0), 135, scl(3.0), scl(8.0), 90, scl(2.2), scl(2.0), 79
  elseif legs = 1
  _drawAppendage x + scl(5.0), y + scl(24.0), scl(3.0), scl(3.0), 34, scl(3.0), scl(8.0), 101, scl(2.5), scl(2.0), 79
  _drawAppendage x - scl(5.0), y + scl(24.0), scl(3.0), scl(3.0), 146, scl(3.0), scl(8.0), 79, scl(2.2), scl(2.0), 101
  elseif legs = 2
    _drawAppendage x + scl(5.0), y + scl(24.0), scl(3.0), scl(3.0), 45, scl(3.0), scl(8.0), 90, scl(2.5), scl(2.0), 101
    _drawAppendage x - scl(5.0), y + scl(24.0), scl(3.0), scl(3.0), 146, scl(3.0), scl(8.0), 79, scl(2.2), scl(2.0), 101
  elseif legs = 3
    _drawAppendage x + scl(5.0), y + scl(24.0), scl(3.0), scl(3.0), 34, scl(3.0), scl(8.0), 101, scl(2.5), scl(2.0), 79
    _drawAppendage x - scl(5.0), y + scl(24.0), scl(3.0), scl(3.0), 135, scl(3.0), scl(8.0), 90, scl(2.2), scl(2.0), 79
  endif
 
  'arms
  if arms =  0
'right arm up
    _drawAppendage x + scl(6.7), y + scl(7.2), scl(3.0), scl(6.0), 315, scl(3.0), scl(9.0), 270, scl(2.5), scl(1.3), 225
    _drawAppendage x - scl(6.7), y + scl(7.2), scl(3.0), scl(9.0), 158, scl(3.0), scl(13.0), 45, scl(2.5), scl(1.3), 225
  elseif arms = 1
'left arm up
    _drawAppendage x - scl(6.7), y + scl(7.2), scl(3.0), scl(6.0), 135, scl(3.0), scl(9.0), 270, scl(2.5), scl(1.3), 315
    _drawAppendage x + scl(6.7), y + scl(7.2), scl(3.0), scl(9.0), 79, scl(3.0), scl(13.0), 101, scl(2.5), scl(1.3), 135
  elseif arms = 2
'Both arms down
    _drawAppendage x + scl(6.7), y + scl(7.2), scl(3.0), scl(9.0), 79, scl(3.0), scl(13.0), 101, scl(2.5), scl(1.3), 135
    _drawAppendage x - scl(6.7), y + scl(7.2), scl(3.0), scl(9.0), 158, scl(3.0), scl(13.0), 45, scl(2.5), scl(1.3), 315
  endif

endproc

function scl(z#)
'scl =scale is visible but not constant in case different scales desired
  return int(z# * curScale# + 0.5)
endfunc

procedure circ(x, y, r) 'rmDisk renamed Rick and MGA from Circ2 test
rsq = r * r; ly = 0
for cx = r downto 0
cy = int(sqr#(float(rsq - cx * cx)))
x1 = x + cx; x2 = x - cx; y1 = y + ly; y2 = y+cy; y3 = y - ly; y4 = y - cy
draw line x1, y1, x1, y2
draw line x1, y3, x1, y4
draw line x2, y1, x2, y2
draw line x2, y3, x2, y4
ly = cy
next
endproc

procedure fcirc2(x0, y0, radius) 'renamed Mopz from Circ2 test
x = radius
y = 0
err = 0
while x >= y
x2 = x*2; y2 = y*2
draw rect x0 - x, y0 + y, x2, 1, true
draw rect x0 - y, y0 + x, y2, 1, true
draw rect x0 - x, y0 - y, x2, 1, true
draw rect x0 - y, y0 - x, y2, 1, true
y = y + 1
err = err + 1 + 2*y
if 2*(err - x) + 1 > 0
x = x - 1
err = err + 1 - 2*x
endif
wend
endproc

'this is better for roundness!!!!!!!!!!!
rem 2015-05-21 mod rmDisk rename and test against Mopz for roundness specially small circles
procedure fcirc(x, y, r)
rsq = r * r
for a = 0 to r
b = int(sqr(float(rsq - a * a)))
x1 = x + a; x2 = x - a; y1 = y - b; y2 = y + b
draw line x1, y1, x1, y2
draw line x2, y1, x2, y2
next
endproc
Title: Re: Online Gorillas / Tanks
Post by: Marcus on September 02, 2016
That looks awesome! Gonna have a good look at it when I get home from work :)
Title: Re: Online Gorillas / Tanks
Post by: Marcus on September 02, 2016
Makes me wanna do something similar but using polygons and the polystuff lib  >:D
Title: Re: Online Gorillas / Tanks
Post by: B+ on September 02, 2016
 :(  I was trying to work out way to use Gorilla arm positions and mouse clicks to aim with one arm and set velocity with the other arm eg a bow in one hand aimed at angle and drawing back the string with the other hand to set the velocity (bananas as long as arrows????) but I have to redo the system of drawing of appendages.

Started testing a system that coverts x,y points into one number to cut the Constants count in half for positions of things.
Title: Re: Online Gorillas / Tanks
Post by: Marcus on September 03, 2016
That sounds extremely complicated, so, uh, keep up the good work :)  I hardly remember the terms for animations like that, some sort of "reverse kinematics" maybe. Biggest problem being the props for the pulling elbow?

Title: Re: Online Gorillas / Tanks
Post by: B+ on September 03, 2016
I am just using drawn circles.

I assume where I draw a circle an image of a circle could be used (and faster!).

But can one circle image be recolored and resized or do you need a separate circle image for each size and color?

 ;D  Maybe a more direct translation of QBasic to Naalaa ?
Title: Re: Online Gorillas / Tanks
Post by: Rick3137 on September 04, 2016
I am just using drawn circles.

I assume where I draw a circle an image of a circle could be used (and faster!).

But can one circle image be recolored and resized or do you need a separate circle image for each size and color?

 

 Mark:
    With NaaLaa, you can make as many blank images as you want at the start of your program. You can then draw circles on the images and display the circles later as fast images. (like sprites)
Title: Re: Online Gorillas / Tanks
Post by: B+ on September 04, 2016
Thanks Rick,

I must have missed that day in class. So, a separate circle image for every size and color then?  :-[
Title: Re: Online Gorillas / Tanks
Post by: Marcus on September 05, 2016
You can also use transformations to draw images scaled and rotated. Awkward to get used to though.

Code: [Select]
' Translate to center of screen.
translate float(width(primary)/2), float(height(primary)/2)

' Rotate 45 degrees
rotate 45.0

' Scale.
scale 0.5, 2.0

' Draw image at current position.
draw image 1

Title: Re: Online Gorillas / Tanks
Post by: B+ on September 10, 2016
Add banana:
Code: [Select]
' Banana throwing.
'mod 2016-09-09 [B+=MGA] give it a banana to toss!

constant:
XMAX = 800
YMAX = 600
hidden:

set window 100, 40, 800, 600
set redraw off

' Forward difference gravity effect.
gravity# = 0.02

' Starting position.
startX = 64
startY = 520

' Power, should be controlled.
power# = 3.5

' Set state to 0 (aim and fire).
state = 0

do
' State 0: Aim and fire.
if state = 0
' Calculate angle.
dx = mousex() - startX
dy = mousey() - startY
if not (dx = 0 and dy = 0)
angle# = atan2(float(dy), float(dx))
endif

' Fire?
if mousebutton(0, true)
state = 1
projX# = float(startX)
projY# = float(startY)
projDX# = cos(angle)*power
projDY# = sin(angle)*power
bAng# = 0.0
endif

' State 1: Projectile in the air.
elseif state = 1
projX = projX + projDX
projY = projY + projDY
projDY = projDY + gravity
' Out of bounds?
if projX < 0.0 or projX >= float(width(primary)) or projY < 0.0 or projY >= float(height(primary))
state = 0
endif
endif


set color 0, 0, 0
cls
set color 255, 255, 255

set caret width(primary)/2, 8
center "Move mouse cursor to aim, click to fire!"

' State 0: Draw aim.
if state = 0
' Arrow.
endX = startX + int(int(cos(angle)*40.0))
endY = startY + int(sin(angle)*40.0)
draw line startX, startY, endX, endY
draw line endX, endY, endX + int(cos(angle - 160.0)*16.0), endY + int(sin(angle - 160.0)*16.0)
draw line endX, endY, endX + int(cos(angle + 160.0)*16.0), endY + int(sin(angle + 160.0)*16.0)

' State 1: Draw projectile.
else
k# = 1.0/sqr(projDX*projDX + projDY*projDY)
dxf# = 8.0*k*projDX
dyf# = 8.0*k*projDY
'draw line int(projX - dxf), int(projY - dyf), int(projX), int(projY)
_drawBanana int(projX - dxf), int(projY - dyf), bAng#
bAng# = bAng# + 5.0 + rndF#(5.0)
endif

redraw
wait 17
until keydown(27, true)



function quad(pStart, r1#, ang#, lng#, r2#)
'solid fill circles at both ends, use polygon 4 points to fill middle area
'draws from pStart at radius r1 down angle ang for length of leg
'with r2 being the radius at end point
'returns the x, y end point in P form for further pendage drawing

'constants XMAX, YMAX
'needs fcirc(x, y, r)
'needs xy2P(x, y)

'extract x, y start line of circles
  fx# = float(pStart % (XMAX + 1))
fy# = float(pStart) / float(XMAX)
x1# = fx# + r1# * cos(ang# + 90.0)
y1# = fy# + r1# * sin(ang# + 90.0)
x2# = fx# + r1# * cos(ang# - 90.0)
y2# = fy# + r1# * sin(ang# - 90.0)

  xe# = fx# + lng# * cos(ang#)
  ye# = fy# + lng# * sin(ang#)
x3# = xe# + r2# * cos(ang# + 90.0)
y3# = ye# + r2# * sin(ang# + 90.0)
x4# = xe# + r2# * cos(ang# - 90.0)
y4# = ye# + r2# * sin(ang# - 90.0)

_fcirc int(fx#), int(fy#), int(r1#)
  _fcirc int(xe#), int(ye#), int(r2#)
'draw quad fill
draw poly[int(x1#), int(y1#), int(x2#), int(y2#), int(x4#), int(y4#), int(x3#), int(y3#)], true
return xy2P(int(xe#), int(ye#))
endfunc

procedure fcirc(x, y, r)
rsq = r * r
for a = 0 to r
b = int(sqr(float(rsq - a * a)))
x1 = x + a; x2 = x - a; y1 = y - b; y2 = y + b
draw line x1, y1, x1, y2
draw line x2, y1, x2, y2
next
endproc

function xy2P(x, y)
'note uses constants XMAX screen width
return y * (XMAX + 1) + x
endfunc

function rndF#(maxFloat#)
'note can't go up to 100,000 maybe 32000?
return maxFloat# * float(rnd(16000)) / 16000.0
endfunc

procedure drawBanana(x, y, ang#)
set colori 0xffff00
startP = xy2P(x, y)
Ang1# = ang# + 45.0
Ang2# = Ang1# + 45.0
midRadius# = 3.0
eRadius# = 1.5
nextP = quad(startP, eRadius#, ang#, 7.0, midRadius#)
nextP = quad(nextP, midRadius#, Ang1#, 7.0, midRadius#)
nextP = quad(nextP, midRadius#, Ang2#, 6.0, eRadius#)
endproc
Title: Re: Online Gorillas / Tanks
Post by: Marcus on September 10, 2016
Haha, awesome :)

Forget the time limit I set in my original post. Haven't had time to do much myself yet, but I'll post some p2p stuff here soon.
Title: Re: Online Gorillas / Tanks
Post by: Rick3137 on September 10, 2016
 Nice work, Mark   :)
Title: Re: Online Gorillas / Tanks
Post by: Marcus on September 11, 2016
Same thing as B+ posted but with a banana image  ;)
Title: Re: Online Gorillas / Tanks
Post by: B+ on September 11, 2016
Oh this is excellent image rotation example!  :)  (and great banana too!)  ;D
Title: Re: Online Gorillas / Tanks
Post by: B+ on September 12, 2016
Combining Marcus code, a game.