_TITLE "eRATication 5 by bplus 2018-08-06" ' QB64 X 64 version 1.2 20180228/86 from git b301f92
' 2018-07-13 eRATication - modified from Asteroids game
' 2018-07-15 eRATication 2
' color rats, eliminate jerks when kill rat,
' decrease rat size as life progresses
' 2018-07-15 some minor changes since post of e #2
' 2018-07-20 eRATication 3
' Shooter: location controlled by mouse
' mouse left and right button works like left and right arrow keys.
' Code: use type for objects, simplify math where possible
' complete makeover of code.
' Fixed problem of running into burning rat.
' Display: Life # and Points on screen as Fellippe suggested.
' Points: should be directly proportional to rat's speed and indirectly
' proportional to size, so speed\size!
' but compare that to number of shots taken!
'2018-08-06 Return of the Cheese Chewer(s)
' All that cheese going to waste?
' nope! redesigned shooter to chucky cheese rat eater
'2018-08-07 eRATication 5:
' The setting is on a cheese floor!
' Back to bullets with cheese wedge shooter BUT!
' they are blue triangle shapes and fire less often,
' not like firing from a water hose BUT
' you can also stab the rats in the abdomen to eRATicate!
' More dramatic bloody mouse explosions from bullet hits.
' Points system: back to 1 rat = current life value.
' I have cut back on rat speeds and shrinking of rats
' as life value increases but now the wedge grows in size adding
' another level of difficulty as life goes on.
'============================== Instructions ==========================
'
' Move cheese wedge (with mouse), stab or aim bullets for rat abdomen
'
' or be eaten!
'
'======================================================================
'screen dimensions
CONST pi56##
= 2.617993877991494 CONST air_resistance
= .85
a
AS _FLOAT 'what will stop the wobble! NOT Integer, single or double
h1&
= _LOADFONT("C:\Windows\Fonts\Arial.ttf", 48)
DIM SHARED life
, nRats
, points
, GameOn
, newRound
, cheese&
, fire
restart:
chucky.x = ww / 2
chucky.y = wh / 2
chucky.r = 50
chucky.a = 0
lastx = ww / 2: lasty = wh / 2
life = 1
nRats = life * ratPack
points = 0
GameOn = 1
newRound = 0
newRat i
growCheese
_PRINTSTRING (80, 350), "Where there is cheese, there is... (press any key)" newRound = 0
'KISS control!!!
'why the heck is this so wobbly???????? I tried everything (exept the right thing) to stop the shaking
IF lastx
<> chucky.x
OR lasty
<> chucky.y
THEN chucky.a
= _R2D(_ATAN2(chucky.y
- lasty
, chucky.x
- lastx
)) lastx = chucky.x: lasty = chucky.y
ELSE 'let no gun idly shoot in same direction chucky.a = chucky.a + 2
chucky.a = chucky.a + 360
chucky.a = chucky.a - 360
drawChucky
stats
handleRats
'chucky goes, round over show last frame to see rat overlap
xx
= chucky.x
+ (chucky.r
+ 20) * COS(ra
) yy
= chucky.y
+ (chucky.r
+ 20) * SIN(ra
) xx2
= chucky.x
+ 5 * chucky.r
* COS(ra
) yy2
= chucky.y
+ 5 * chucky.r
* SIN(ra
) ln xx
, yy
, xx2
, yy2
, _RGB32(200, 0, 0) life = life + 1
nRats = life * ratPack
'new set o rats
newRat i
GameOn = 0
handleBullets
chucky.r
= 50 + INT(points
/ 5) IF chucky.r
> 150 THEN chucky.r
= 150 _DELAY 4 ' pause to examine score, ' no play again prompt necessary, of course you want to play again!
IF b
(i
).live
= 0 AND fire
= 1 THEN 'have in active bullet index to use b
(i
).x
= chucky.x
+ (chucky.r
+ 5) * COS(rA
) b
(i
).y
= chucky.y
+ (chucky.r
+ 5) * SIN(rA
) b
(i
).dx
= bSpeed
* COS(rA
) b
(i
).dy
= bSpeed
* SIN(rA
) b(i).live = 1
fire = 0
IF b
(i
).live
= 1 THEN 'new location b(i).x = b(i).x + b(i).dx
b(i).y = b(i).y + b(i).dy
IF b
(i
).x
> 0 AND b
(i
).x
< ww
AND b
(i
).y
> 0 AND b
(i
).y
< wh
THEN 'in bounds draw it 'check for collision with rat
IF ((r
(r
).x
- b
(i
).x
) ^ 2 + (r
(r
).y
- b
(i
).y
) ^ 2) ^ .5 < r
(r
).r
THEN r(r).dead = 1
points = points + life
b(i).live = 0
ba
= _ATAN2(b
(i
).dy
, b
(i
).dx
): b
= 15 x1
= b
(i
).x
+ b
* COS(ba
) y1
= b
(i
).y
+ b
* SIN(ba
) x2
= b
(i
).x
+ b
* COS(ba
+ _PI(5 / 6)) y2
= b
(i
).y
+ b
* SIN(ba
+ _PI(5 / 6)) x3
= b
(i
).x
+ b
* COS(ba
+ _PI(7 / 6)) y3
= b
(i
).y
+ b
* SIN(ba
+ _PI(7 / 6)) fTri x1
, y1
, x2
, y2
, x3
, y3
, _RGB32(0, 0, 160) 'fcirc b(i).x, b(i).y, 4, _RGB32(64, 0, 0)
b(i).live = 0
side = rand(1, 4)
r(iRat).x = 0: r(iRat).y = rand(0, wh)
r(iRat).dx = rand(1, 6) * m: r(iRat).dy = rand(-4, 4) * m
r(iRat).x = ww: r(iRat).y = rand(0, wh)
r(iRat).dx = rand(-6, -1) * m: r(iRat).dy = rand(-4, 4) * m
r(iRat).x = rand(0, ww): r(iRat).y = 0
r(iRat).dx = rand(-6, 6) * m: r(iRat).dy = rand(1, 4) * m
r(iRat).x = rand(0, ww): r(iRat).y = wh:
r(iRat).dx = rand(-6, 6) * m: r(iRat).dy = rand(-4, -1) * m
r(iRat).r = rand(10, 60 / m)
r(iRat).dead = 0
r = rand(30, 150): g = r \ 2 + rand(0, 20): b = g \ 2 + rand(-2, 15)
IF r
(i
).dead
= 0 THEN 'if rat not dead move it r(i).x = r(i).x + r(i).dx
r(i).y = r(i).y + r(i).dy
' rat collides with chucky:
IF ((r
(i
).x
- chucky.x
) ^ 2 + (r
(i
).y
- chucky.y
) ^ 2) ^ .5 < .85 * chucky.r
AND r
(i
).dead
= 0 THEN 'Who gets who ??
'if rat (abdomen) in chucky's mouth chucky lives, rat dies... otherwise vice versa
'we can determine this from the angle between two centers and the direction = direction of chucky's mouth
mx
= chucky.x
+ .5 * chucky.r
* COS(cra
) my
= chucky.y
+ .5 * chucky.r
* SIN(cra
) IF ((r
(i
).x
- mx
) ^ 2 + (r
(i
).y
- my
) ^ 2) ^ .5 < .65 * chucky.r
THEN 'very near center of mouth 'rat dies
r(i).dead = -1
points = points + life
newRound = 1 'draw rest of rats to show collisions
'is the rat on screen
IF r
(i
).x
> 0 AND r
(i
).x
< ww
AND r
(i
).y
> 0 AND r
(i
).y
< wh
THEN 'inbounds IF r
(i
).dead
THEN 'show the burn out until reaches rat radius IF r
(i
).dead
< 0 THEN 'death by stabbing r(i).dead = r(i).dead - 6
fcirc r
(i
).x
, r
(i
).y
, r
(i
).r
+ r
(i
).dead
, _RGB32(255 + r
(i
).dead
, 128 + r
(i
).dead
, 0) explode r(i).x, r(i).y, r(i).r, r(i).r + r(i).dead
r(i).dead = r(i).dead + 6
fcirc r
(i
).x
, r
(i
).y
, r
(i
).r
- r
(i
).dead
, _RGB32(255 - r
(i
).dead
, 128 - r
(i
).dead
, 0) explode r(i).x, r(i).y, r(i).r, r(i).r - r(i).dead
newRat i
'draw it
heading
= _ATAN2(r
(i
).dy
, r
(i
).dx
) noseX
= r
(i
).x
+ 2 * r
(i
).r
* COS(heading
) noseY
= r
(i
).y
+ 2 * r
(i
).r
* SIN(heading
) neckX
= r
(i
).x
+ .75 * r
(i
).r
* COS(heading
) neckY
= r
(i
).y
+ .75 * r
(i
).r
* SIN(heading
) tailX
= r
(i
).x
+ 2 * r
(i
).r
* COS(heading
+ _PI) tailY
= r
(i
).y
+ 2 * r
(i
).r
* SIN(heading
+ _PI) earLX
= r
(i
).x
+ r
(i
).r
* COS(heading
- _PI(1 / 12)) earLY
= r
(i
).y
+ r
(i
).r
* SIN(heading
- _PI(1 / 12)) earRX
= r
(i
).x
+ r
(i
).r
* COS(heading
+ _PI(1 / 12)) earRY
= r
(i
).y
+ r
(i
).r
* SIN(heading
+ _PI(1 / 12)) fcirc r(i).x, r(i).y, .65 * r(i).r, r(i).c
fcirc neckX, neckY, r(i).r * .3, r(i).c
fTri noseX, noseY, earLX, earLY, earRX, earRY, r(i).c
fcirc earLX, earLY, r(i).r * .3, r(i).c
fcirc earRX, earRY, r(i).r * .3, r(i).c
wX
= .5 * r
(i
).r
* COS(heading
- _PI(11 / 18)) wY
= .5 * r
(i
).r
* SIN(heading
- _PI(11 / 18)) ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, r(i).c
wX
= .5 * r
(i
).r
* COS(heading
- _PI(7 / 18)) wY
= .5 * r
(i
).r
* SIN(heading
- _PI(7 / 18)) ln noseX + wX, noseY + wY, noseX - wX, noseY - wY, r(i).c
ln r(i).x, r(i).y, tailX, tailY, r(i).c
newRat i
'first makeCheese and use cheese& image to build chucky image
'dim shared chucky as cheeseType
'next first leg of chucky
x1
= chucky.x
+ chucky.r
* COS(cra
) y1
= chucky.y
+ chucky.r
* SIN(cra
) x2
= chucky.x
+ chucky.r
* COS(cra
+ pi56##
) y2
= chucky.y
+ chucky.r
* SIN(cra
+ pi56##
)
'first leg of cheese
cx1
= cx0
+ chucky.r
* COS(0) cy1
= cy0
+ chucky.r
* SIN(0) cx2
= cx0
+ chucky.r
* COS(pi56##
) cy2
= cy0
+ chucky.r
* SIN(pi56##
)
'take small traingles off cheese& image and map them onto main screen at chucky's and mouth angle position
starter = pi56## + stepper
'one to one ratio of mapping
x3
= chucky.x
+ chucky.r
* COS(cra
+ a
) y3
= chucky.y
+ chucky.r
* SIN(cra
+ a
) cx3
= cx0
+ chucky.r
* COS(a
) cy3
= cy0
+ chucky.r
* SIN(a
) _MAPTRIANGLE (cx1
, cy1
)-(cx2
, cy2
)-(cx3
, cy3
), cheese&
TO(x1
, y1
)-(x2
, y2
)-(x3
, y3
), 0 x2 = x3: y2 = y3: cx2 = cx3: cy2 = cy3
pieSlice x1
, y1
, 2 * chucky.r
, cra
+ _PI(11 / 12), cra
+ _PI(13 / 12), _RGB32(0, 0, 0)
SUB growCheese
() 'make this more self contained than first version, all hole stuff just in here nHoles = ww * wh / 1000: maxHoleLife = 20: maxHoleRadius = 7: tfStart = 1
DIM hx
(nHoles
), hy
(nHoles
), hLife
(nHoles
) tfStart = 0
LINE (0, 0)-(ww
, wh
), _RGBA32(255, 255, 0, 50), BF
'layer of cheese FOR i
= 1 TO nHoles
'holes in layer IF hLife
(i
) + 1 > maxHoleLife
THEN GOSUB newHole
ELSE hLife
(i
) = hLife
(i
) + 1 hx
(i
) = hx
(i
) + RND * 2 - 1 hy
(i
) = hy
(i
) + RND * 2 - 1 IF hLife
(i
) < maxHoleRadius
THEN radius = hLife(i)
ELSEIF maxHoleLife
- hLife
(i
) < maxHoleRadius
THEN radius = maxHoleLife - hLife(i)
radius = maxHoleRadius
fcirc hx
(i
), hy
(i
), radius
, _RGBA32(0, 0, 0, 50)
newHole:
SUB explode
(x
, y
, r
, frm
) maxParticles = r * 10
NewDot i, x, y, r
rounds = r
dots(i).x = dots(i).x + dots(i).dx
dots(i).y = dots(i).y + dots(i).dy
dots(i).dx = dots(i).dx * air_resistance
dots(i).dy = air_resistance * dots(i).dy
fcirc dots(i).x, dots(i).y, dots(i).size / 2, dots(i).kolor
NewDot (rounds + i), x, y, r
rounds = rounds + r
dots
(i
).x
= x
+ rd
* COS(angle
) dots
(i
).y
= y
+ rd
* SIN(angle
) dots
(i
).size
= RND * r
* .1 rd
= RND 'STxAxTIC recommended for rounder spreads dots
(i
).dx
= rd
* 7 * (7 - dots
(i
).size
) * COS(angle
) dots
(i
).dy
= rd
* 7 * (7 - dots
(i
).size
) * SIN(angle
) dots
(i
).kolor
= _RGB32(140 + rd
* 80, rd
* 40, 0)
rand%
= INT(RND * (hi%
- lo%
+ 1)) + lo%
' found at [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]: http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
LINE (x1
, y1
)-(x2
, y2
), K
'Steve McNeil's copied from his forum note: Radius is too common a name
RadiusError = -subRadius
X = subRadius
Y = 0
' Draw the middle span here so we don't draw it twice in the main loop,
' which would be a problem with blending turned on.
LINE (CX
- X
, CY
)-(CX
+ X
, CY
), c
, BF
RadiusError = RadiusError + Y * 2 + 1
LINE (CX
- Y
, CY
- X
)-(CX
+ Y
, CY
- X
), c
, BF
LINE (CX
- Y
, CY
+ X
)-(CX
+ Y
, CY
+ X
), c
, BF
X = X - 1
RadiusError = RadiusError - X * 2
Y = Y + 1
LINE (CX
- X
, CY
- Y
)-(CX
+ X
, CY
- Y
), c
, BF
LINE (CX
- X
, CY
+ Y
)-(CX
+ X
, CY
+ Y
), c
, BF
'use radians
'x, y origin, r = radius, c = color
'raStart is first angle clockwise from due East = 0 degrees
' arc will start drawing there and clockwise until raStop angle reached
arc x
, y
, r
, raStart
, _PI(2), c
arc x, y, r, 0, raStop, c
' modified to easier way suggested by Steve
'Why was the line method not good? I forgot.
al
= _PI * r
* r
* (raStop
- raStart
) / _PI(2)
'draw lines from origin to arc on sides
arc x, y, r, raStart, raStop, c
px
= x
+ r
* COS(raStart
): py
= y
+ r
* SIN(raStart
) px
= x
+ r
* COS(raStop
): py
= y
+ r
* SIN(raStop
)