From 45081099a56c02f9a19d586cda438c12fee4ed73 Mon Sep 17 00:00:00 2001 From: Ryan Schenk Date: Fri, 28 Dec 2018 17:12:55 -0500 Subject: [PATCH] Perform hit detection in physical LED space Previously hit detection was done in virtual LED space (i.e. 0-1000) but this caused some weirdness, especially with a small number of LED. For example you could end up in a situation where visually the edge of an attack totally hits an enemy, but the enemy does not die...because in virtual space the attack didn't quite reach the enemy even though they are aliased to the same LED on the strip. This was confusing. Now all hit detection is done in the actual LED space, so what you see is what you get. --- TWANG.ino | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/TWANG.ino b/TWANG.ino index 78b9681..f0ff6ee 100644 --- a/TWANG.ino +++ b/TWANG.ino @@ -19,7 +19,7 @@ */ -#define VERSION "2018-04-16" +#define VERSION "2018-12-28" // Required libs #include "FastLED.h" @@ -96,8 +96,9 @@ enum stages { int score; long stageStartTime; // Stores the time the stage changed for stages that are time based -int playerPosition; // Stores the player position +int playerPosition; // Stores the player position in virtual space int playerPositionModifier; // +/- adjustment to player position +int playerPositionLED; // Stores the player position in LED space bool playerAlive; long killTime; uint8_t lives; @@ -263,7 +264,11 @@ void loop() { } } - if(inLava(playerPosition)){ + // Now that all movement is taken care of, compute player's + // position in LED space once, for use in hit detection, etc + playerPositionLED = getLED(playerPosition); + + if(inLava(playerPositionLED)){ die(); } @@ -641,25 +646,26 @@ void tickEnemies(){ for(int i = 0; i playerPosition-(attack_width/2) && enemyPool[i]._pos < playerPosition+(attack_width/2)){ + if(enemyPositionLED >= getLED(playerPosition-(attack_width/2)) && enemyPositionLED <= getLED(playerPosition+(attack_width/2))){ enemyPool[i].Kill(); SFXkill(); } } - if(inLava(enemyPool[i]._pos)){ + if(inLava(enemyPositionLED)){ enemyPool[i].Kill(); SFXkill(); } // Draw (if still alive) if(enemyPool[i].Alive()) { - leds[getLED(enemyPool[i]._pos)] = CRGB(255, 0, 0); + leds[enemyPositionLED] = CRGB(255, 0, 0); } // Hit player? if( - (enemyPool[i].playerSide == 1 && enemyPool[i]._pos <= playerPosition) || - (enemyPool[i].playerSide == -1 && enemyPool[i]._pos >= playerPosition) + (enemyPool[i].playerSide == 1 && enemyPositionLED <= playerPositionLED) || + (enemyPool[i].playerSide == -1 && enemyPositionLED >= playerPositionLED) ){ die(); return; @@ -700,8 +706,8 @@ void tickBoss(){ } void drawPlayer(){ - leds[getLED(playerPosition)] = CRGB(0, 255, 0); -} + leds[playerPositionLED] = CRGB(0, 255, 0); +} void drawExit(){ if(!boss.Alive()){ @@ -954,10 +960,10 @@ void drawAttack(){ } if(n > 90) { n = 255; - leds[getLED(playerPosition)] = CRGB(255, 255, 255); + leds[playerPositionLED] = CRGB(255, 255, 255); }else{ n = 0; - leds[getLED(playerPosition)] = CRGB(0, 255, 0); + leds[playerPositionLED] = CRGB(0, 255, 0); } leds[getLED(playerPosition-(attack_width/2))] = CRGB(n, n, 255); leds[getLED(playerPosition+(attack_width/2))] = CRGB(n, n, 255); @@ -968,14 +974,18 @@ int getLED(int pos){ return constrain((int)map(pos, 0, VIRTUAL_LED_COUNT, 0, user_settings.led_count-1), 0, user_settings.led_count-1); } -bool inLava(int pos){ +// Note that you must pass the position in LED space here, +// as hit detection is done in this space +bool inLava(int positionLED){ // Returns if the player is in active lava int i; Lava LP; for(i = 0; i pos) return true; + int left_led = getLED(LP._left), + right_led = getLED(LP._right); + if(left_led <= positionLED && right_led >= positionLED) return true; } } return false;