(02-17-2024, 07:01 PM)johnno56 Wrote: See? See that? See what you did? "Imagine a shootemup..." then move into a brief description.... Creative thinking! There must be a tutorial on how to do that... Formulate an idea, translate that idea into code, so that others can enjoy or understand the idea. I am amazed that you seemingly came up with that concept relatively quickly and easily. You sir, have a wonderful gift... *sigh* Well done!
Thank you, sir!
It didn't look quite as cool as I expected though, but this was just a quick test. Very dirty code, needs cleaning:
Code:
#win32
constant SQUARE = 24
visible enemies
set window "Square enemies", 640, 480
set redraw off
' Create a big enemy.
bigEnemy = BigEnemy()
' Create as many small enemies as there are pieces in the big enemy's shape.
enemies = []
foreach row in bigEnemy.GetShape() foreach piece in row
if piece enemies[sizeof(enemies)] = SmallEnemy()
next
lastTick = clock()
while not keydown(KEY_ESCAPE, true)
t = clock()
dt = (t - lastTick)/1000
lastTick = t
bigEnemy.Update(dt)
foreach enemy in enemies enemy.Update(dt)
set color 0, 0, 0
cls
foreach enemy in enemies enemy.Draw()
redraw
wait 1
wend
' BigEnemy
' --------
' Return a big enemy.
function BigEnemy()
e = []
' Shape of the big guy.
e.shape = [
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[1, 0, 1, 1, 1, 1, 1, 0, 1],
[1, 1, 0, 1, 1, 1, 0, 1, 1],
[0, 1, 0, 0, 1, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 0, 1, 1, 1, 0, 1, 1],
[1, 0, 0, 1, 0, 1, 0, 0, 1],
[1, 1, 0, 1, 0, 1, 0, 1, 1]]
' True when shaped by small enemies.
e.hasForm = false
e.formTimer = 2
' Size and position.
e.w = sizeof(e.shape[0])*SQUARE
e.h = sizeof(e.shape)*SQUARE
e.x = (width(primary) - e.w)/2
e.y = (height(primary) - e.h)/2
' Movement.
e.dx = 0
e.dy = 0
e.wdx = 0
e.wdy = 0
' Get shape.
e.GetShape = function()
return this.shape
endfunc
' Get the x position of a piece.
e.PieceX = function(x)
return this.x + x*SQUARE
endfunc
' Get the y position of a piece.
e.PieceY = function(y)
return this.y + y*SQUARE
endfunc
' Set a random direction.
e.SetRandomDirection = function()
this.turnTimer = 2 + rnd()*2
a = rnd(360)
this.wdx = cos(rad(a))*50
this.wdy = sin(rad(a))*50
endfunc
' Update
e.Update = function(dt)
' Form.
this.formTimer = max(this.formTimer - dt, 0)
if this.formTimer = 0
if this.hasForm
this.hasForm = false
if rnd(2) = 0
this.formTimer = 0.1 + rnd()*0.4
else
this.formTimer = 4 + rnd()*3
endif
else
this.hasForm = true
this.formTimer = 6 + rnd()
' Assign positions in the shape to enemies.
this.ShapeEnemies()
endif
endif
' Move.
i = 1.5*dt
this.dx = this.dx*(1 - i) + this.wdx*i
this.dy = this.dy*(1 - i) + this.wdy*i
this.x = this.x + this.dx*dt
if this.x < 0 this.wdx = |this.wdx|
elseif this.x + this.w > width(primary) this.wdx = -|this.wdx|
this.y = this.y + this.dy*dt
if this.y < 0 this.wdy = |this.wdy|
elseif this.y + this.h > height(primary) this.wdy = -|this.wdy|
this.turnTimer = this.turnTimer - dt
if this.turnTimer <= 0 this.SetRandomDirection()
return true
endfunc
' Assign positions in shape to enemies.
e.ShapeEnemies = function()
' Uhm ... this list could be generated just once.
positions = []
for y = 0 to sizeof(this.shape) - 1 for x = 0 to sizeof(this.shape[0]) - 1
if this.shape[y][x] positions[sizeof(positions)] = [x, y]
next
' Assign shape positions to enemies.
foreach e in enemies
if not sizeof(positions) break
index = rnd(sizeof(positions))
e.SetBigEnemy(this, positions[index][0], positions[index][1])
free key positions, index
next
endfunc
e.SetRandomDirection()
return e
endfunc
' SmallEnemy
' ----------
' Return a small enemy.
function SmallEnemy()
e = []
' Its own position.
e.selfX = rnd(640 - SQUARE)
e.selfY = rnd(480 - SQUARE)
' Size.
e.w = SQUARE
e.h = SQUARE
' Movement.
e.dx = 0
e.dy = 0
e.wdx = 0
e.wdy = 0
e.turnTimer = 0
' Gets set when connected to a big enemy.
e.bigEnemy = unset
' Set a random direction.
e.SetRandomDirection = function()
this.turnTimer = 2 + rnd()*2
a = rnd(360)
this.wdx = cos(rad(a))*100
this.wdy = sin(rad(a))*100
endfunc
' Set big enemy.
e.SetBigEnemy = function(bigEnemy, x, y)
this.bigEnemy = bigEnemy
this.bigX = x
this.bigY = y
this.formParam = 0
this.formSpeed = 0.3 + rnd()*0.2
endfunc
' Update.
e.Update = function(dt)
' Update personal position.
i = 1.5*dt
this.dx = this.dx*(1 - i) + this.wdx*i
this.dy = this.dy*(1 - i) + this.wdy*i
this.selfX = this.selfX + this.dx*dt
if this.selfX < 0 this.wdx = |this.wdx|
elseif this.selfX + this.w > width(primary) this.wdx = -|this.wdx|
this.selfY = this.selfY + this.dy*dt
if this.selfY < 0 this.wdy = |this.wdy|
elseif this.selfY + this.h > height(primary) this.wdy = -|this.wdy|
this.turnTimer = this.turnTimer - dt
if this.turnTimer <= 0 this.SetRandomDirection()
' Combine self position with position given by big enemy.
if this.bigEnemy
' Does it still have a form?
if this.bigEnemy.hasForm
this.formParam = min(this.formParam + this.formSpeed*dt, 1)
p = this.formParam^2
this.x = this.selfX*(1 - p) + this.bigEnemy.PieceX(this.bigX)*p
this.y = this.selfY*(1 - p) + this.bigEnemy.PieceY(this.bigY)*p
' "explode"
else
a = rnd(360)
this.wdx = this.x + this.w/2 - (this.bigEnemy.x + this.bigEnemy.w/2)
this.wdy = this.y + this.h/2 - (this.bigEnemy.y + this.bigEnemy.h/2)
k = 200/sqr(this.wdx*this.wdx + this.wdy*this.wdy)
this.wdx = 0.8*this.wdx*k + 0.2*cos(rad(a))*200
this.wdy = 0.8*this.wdy*k + 0.2*sin(rad(a))*200
this.dx = this.wdx
this.dy = this.wdy
this.turnTimer = 0.25 + rnd()*0.5
this.selfX = this.x
this.selfY = this.y
this.bigEnemy = unset
endif
' Only use self position.
else
this.x = this.selfX
this.y = this.selfY
endif
endfunc
' Draw.
e.Draw = function()
set color 0, 200, 0
draw rect this.x, this.y, SQUARE, SQUARE, true
set color 64, 255, 64
draw line this.x, this.y, this.x + SQUARE - 1, this.y
draw line this.x, this.y, this.x, this.y + SQUARE - 1
endfunc
e.SetRandomDirection()
return e
endfunc
Sorry for hijacking your post, aliensoldier.