' D/BASIC port of the official GX physics/gravity.bas sample. ' ' Original sample and assets copyright (c) 2021 boxgaming, MIT licensed. ' This port keeps the official sample's controls, player, reusable bullets, ' gravity, platforms, and collision rules. Its original PNG sprites and GXM ' map ship in gx-gravity-assets; this alpha live path expresses that material ' with current GFX primitives until named resources join the browser provider. IMPORT gx CONST PLAYER = 0 CONST PLATFORM_ONE = 1 CONST PLATFORM_TWO = 2 CONST FLOOR_ENTITY = 3 CONST BULLET_FIRST = 4 CONST BULLET_COUNT = 10 CONST RIGHT = 2 CONST LEFT = 1 CONST SKY = 8456 CONST GROUND = 10697 CONST GROUND_EDGE = 21162 CONST PLAYER_RED = -1835 CONST PLAYER_WHITE = -1 CONST COIN_GOLD = -1120 DIM SHARED Scene(0 TO 7) AS INTEGER DIM SHARED Entities(0 TO 139) AS INTEGER DIM SHARED Camera(0 TO 1) AS INTEGER DIM SHARED BulletAlive(0 TO 9) AS INTEGER DIM SHARED BulletNext AS INTEGER DIM SHARED Direction AS INTEGER DIM SHARED AnimationTick AS INTEGER DIM SHARED Paused AS INTEGER DECLARE SUB EntitySetPosition(Slot AS INTEGER, X AS INTEGER, Y AS INTEGER) DECLARE SUB EntitySetVelocity(Slot AS INTEGER, VX AS INTEGER, VY AS INTEGER) DECLARE SUB StepPlayer() DECLARE SUB StepBullets() DECLARE SUB Shoot() DECLARE SUB DrawMap() DECLARE SUB DrawEntity(Slot AS INTEGER, Color AS INTEGER) DECLARE SUB DrawPlayer() DECLARE SUB DrawBullets() WINDOW SUB OPEN() CALL GXSceneOpen(Scene(), 320, 192) CALL GXEntitySpawn(Entities(), PLAYER, 20, 0, 16, 20, 1) CALL GXEntitySpawn(Entities(), PLATFORM_ONE, 40, 140, 100, 20, 2) CALL GXEntitySpawn(Entities(), PLATFORM_TWO, 200, 80, 100, 20, 2) CALL GXEntitySpawn(Entities(), FLOOR_ENTITY, 0, 184, 320, 8, 2) Direction = RIGHT BulletNext = 0 AnimationTick = 0 Paused = 0 SERVICE SET_TITLE("GX Gravity - official sample") END SUB WINDOW SUB DRAW() IF Paused = 0 THEN CALL GXSceneAdvance(Scene()) CALL StepPlayer() CALL StepBullets() AnimationTick = AnimationTick + 1 IF AnimationTick > 30000 THEN AnimationTick = 0 END IF INTENT GFX.BEGIN_FRAME() INTENT GFX.FILL_RECT(0, 0, 320, 192, SKY) CALL DrawMap() CALL DrawEntity(PLATFORM_ONE, GROUND) CALL DrawEntity(PLATFORM_TWO, GROUND) CALL DrawEntity(FLOOR_ENTITY, GROUND) CALL DrawPlayer() CALL DrawBullets() INTENT GFX.DRAW_TEXT(8, 7, "A/D move K jump J fire P pause", 2, PLAYER_WHITE, SKY) IF Paused <> 0 THEN INTENT GFX.FILL_RECT(112, 80, 96, 28, 0) INTENT GFX.DRAW_TEXT(129, 86, "PAUSED", 3, PLAYER_WHITE, 0) END IF INTENT GFX.PRESENT() SERVICE INVALIDATE() END SUB WINDOW SUB CLOSE() END SUB ON KEY SUB (K AS INTEGER) DIM EntityAt AS INTEGER EntityAt = GXEntityBase(Entities(), PLAYER) IF K = 65 OR K = 97 THEN Entities(EntityAt + GX_ENTITY_VX_AT) = -3 Direction = LEFT END IF IF K = 68 OR K = 100 THEN Entities(EntityAt + GX_ENTITY_VX_AT) = 3 Direction = RIGHT END IF IF K = 75 OR K = 107 THEN IF Entities(EntityAt + GX_ENTITY_VY_AT) = 0 THEN Entities(EntityAt + GX_ENTITY_VY_AT) = -9 END IF IF K = 74 OR K = 106 THEN CALL Shoot() IF K = 80 OR K = 112 THEN Paused = NOT Paused END SUB SUB EntitySetPosition(Slot AS INTEGER, X AS INTEGER, Y AS INTEGER) DIM EntityAt AS INTEGER EntityAt = GXEntityBase(Entities(), Slot) Entities(EntityAt + GX_ENTITY_X_AT) = X Entities(EntityAt + GX_ENTITY_Y_AT) = Y END SUB SUB EntitySetVelocity(Slot AS INTEGER, VX AS INTEGER, VY AS INTEGER) DIM EntityAt AS INTEGER EntityAt = GXEntityBase(Entities(), Slot) Entities(EntityAt + GX_ENTITY_VX_AT) = VX Entities(EntityAt + GX_ENTITY_VY_AT) = VY END SUB SUB StepPlayer() DIM EntityAt AS INTEGER DIM Platform AS INTEGER DIM PlatformBase AS INTEGER DIM PreviousY AS INTEGER EntityAt = GXEntityBase(Entities(), PLAYER) PreviousY = Entities(EntityAt + GX_ENTITY_Y_AT) IF Entities(EntityAt + GX_ENTITY_VY_AT) < 8 THEN Entities(EntityAt + GX_ENTITY_VY_AT) = Entities(EntityAt + GX_ENTITY_VY_AT) + 1 CALL GXEntityStep(Entities(), PLAYER) IF Entities(EntityAt + GX_ENTITY_X_AT) < 0 THEN Entities(EntityAt + GX_ENTITY_X_AT) = 0 IF Entities(EntityAt + GX_ENTITY_X_AT) > 304 THEN Entities(EntityAt + GX_ENTITY_X_AT) = 304 IF Entities(EntityAt + GX_ENTITY_VY_AT) >= 0 THEN FOR Platform = PLATFORM_ONE TO FLOOR_ENTITY PlatformBase = GXEntityBase(Entities(), Platform) IF PreviousY + 20 <= Entities(PlatformBase + GX_ENTITY_Y_AT) + 2 THEN IF GXEntitiesOverlap(Entities(), PLAYER, Platform) <> 0 THEN Entities(EntityAt + GX_ENTITY_Y_AT) = Entities(PlatformBase + GX_ENTITY_Y_AT) - 20 Entities(EntityAt + GX_ENTITY_VY_AT) = 0 END IF END IF NEXT Platform END IF IF Entities(EntityAt + GX_ENTITY_Y_AT) > 192 THEN CALL EntitySetPosition(PLAYER, 20, 0) CALL EntitySetVelocity(PLAYER, 0, 0) END IF IF Entities(EntityAt + GX_ENTITY_VX_AT) > 0 THEN Entities(EntityAt + GX_ENTITY_VX_AT) = Entities(EntityAt + GX_ENTITY_VX_AT) - 1 IF Entities(EntityAt + GX_ENTITY_VX_AT) < 0 THEN Entities(EntityAt + GX_ENTITY_VX_AT) = Entities(EntityAt + GX_ENTITY_VX_AT) + 1 END SUB SUB StepBullets() DIM I AS INTEGER DIM Slot AS INTEGER DIM EntityAt AS INTEGER DIM Platform AS INTEGER IF BULLET_COUNT <= 0 THEN EXIT SUB FOR I = 0 TO BULLET_COUNT - 1 IF BulletAlive(I) <> 0 THEN Slot = BULLET_FIRST + I EntityAt = GXEntityBase(Entities(), Slot) IF Entities(EntityAt + GX_ENTITY_VY_AT) < 8 THEN Entities(EntityAt + GX_ENTITY_VY_AT) = Entities(EntityAt + GX_ENTITY_VY_AT) + 1 CALL GXEntityStep(Entities(), Slot) FOR Platform = PLATFORM_ONE TO FLOOR_ENTITY IF GXEntitiesOverlap(Entities(), Slot, Platform) <> 0 THEN BulletAlive(I) = 0 NEXT Platform IF Entities(EntityAt + GX_ENTITY_X_AT) < -16 OR Entities(EntityAt + GX_ENTITY_X_AT) > 320 THEN BulletAlive(I) = 0 IF Entities(EntityAt + GX_ENTITY_Y_AT) > 192 THEN BulletAlive(I) = 0 END IF NEXT I END SUB SUB Shoot() DIM Slot AS INTEGER DIM EntityAt AS INTEGER DIM PlayerBase AS INTEGER Slot = BULLET_FIRST + BulletNext IF Entities(GXEntityBase(Entities(), Slot) + GX_ENTITY_ALIVE_AT) = 0 THEN CALL GXEntitySpawn(Entities(), Slot, 0, 0, 10, 10, 3) END IF EntityAt = GXEntityBase(Entities(), Slot) PlayerBase = GXEntityBase(Entities(), PLAYER) IF Direction = RIGHT THEN Entities(EntityAt + GX_ENTITY_X_AT) = Entities(PlayerBase + GX_ENTITY_X_AT) + 12 Entities(EntityAt + GX_ENTITY_VX_AT) = 6 ELSE Entities(EntityAt + GX_ENTITY_X_AT) = Entities(PlayerBase + GX_ENTITY_X_AT) - 6 Entities(EntityAt + GX_ENTITY_VX_AT) = -6 END IF Entities(EntityAt + GX_ENTITY_Y_AT) = Entities(PlayerBase + GX_ENTITY_Y_AT) + 6 Entities(EntityAt + GX_ENTITY_VY_AT) = -3 BulletAlive(BulletNext) = -1 BulletNext = BulletNext + 1 IF BulletNext >= BULLET_COUNT THEN BulletNext = 0 END SUB SUB DrawMap() DIM Y AS INTEGER INTENT GFX.FILL_RECT(0, 64, 48, 128, GROUND_EDGE) INTENT GFX.FILL_RECT(16, 80, 32, 112, GROUND) INTENT GFX.FILL_RECT(272, 128, 48, 64, GROUND_EDGE) INTENT GFX.FILL_RECT(208, 160, 64, 32, GROUND_EDGE) FOR Y = 64 TO 176 STEP 16 INTENT GFX.FILL_RECT(0, Y, 2, 14, PLAYER_WHITE) NEXT Y END SUB SUB DrawEntity(Slot AS INTEGER, Color AS INTEGER) DIM EntityAt AS INTEGER EntityAt = GXEntityBase(Entities(), Slot) INTENT GFX.FILL_RECT(Entities(EntityAt + GX_ENTITY_X_AT), Entities(EntityAt + GX_ENTITY_Y_AT), Entities(EntityAt + GX_ENTITY_WIDTH_AT), Entities(EntityAt + GX_ENTITY_HEIGHT_AT), Color) INTENT GFX.FILL_RECT(Entities(EntityAt + GX_ENTITY_X_AT), Entities(EntityAt + GX_ENTITY_Y_AT), Entities(EntityAt + GX_ENTITY_WIDTH_AT), 2, GROUND_EDGE) END SUB SUB DrawPlayer() DIM EntityAt AS INTEGER DIM X AS INTEGER DIM Y AS INTEGER DIM StepFrame AS INTEGER EntityAt = GXEntityBase(Entities(), PLAYER) X = Entities(EntityAt + GX_ENTITY_X_AT) Y = Entities(EntityAt + GX_ENTITY_Y_AT) StepFrame = GXAnimationFrame(0, 2, AnimationTick, 6) INTENT GFX.FILL_RECT(X + 4, Y, 8, 5, PLAYER_WHITE) INTENT GFX.FILL_RECT(X + 3, Y + 5, 10, 6, PLAYER_RED) INTENT GFX.FILL_RECT(X + 2, Y + 11, 12, 7, PLAYER_RED) IF StepFrame = 0 THEN INTENT GFX.FILL_RECT(X + 3, Y + 18, 4, 2, 0) INTENT GFX.FILL_RECT(X + 10, Y + 18, 4, 2, 0) ELSE INTENT GFX.FILL_RECT(X + 5, Y + 18, 4, 2, 0) INTENT GFX.FILL_RECT(X + 8, Y + 18, 4, 2, 0) END IF IF Direction = RIGHT THEN INTENT GFX.FILL_RECT(X + 10, Y + 3, 2, 2, 0) ELSE INTENT GFX.FILL_RECT(X + 4, Y + 3, 2, 2, 0) END IF END SUB SUB DrawBullets() DIM I AS INTEGER DIM Slot AS INTEGER DIM EntityAt AS INTEGER DIM X AS INTEGER DIM Y AS INTEGER FOR I = 0 TO BULLET_COUNT - 1 IF BulletAlive(I) <> 0 THEN Slot = BULLET_FIRST + I EntityAt = GXEntityBase(Entities(), Slot) X = Entities(EntityAt + GX_ENTITY_X_AT) Y = Entities(EntityAt + GX_ENTITY_Y_AT) INTENT GFX.FILL_RECT(X + 2, Y, 6, 10, COIN_GOLD) INTENT GFX.FILL_RECT(X, Y + 2, 10, 6, COIN_GOLD) INTENT GFX.FILL_RECT(X + 4, Y + 2, 2, 6, PLAYER_WHITE) END IF NEXT I END SUB