kopia lustrzana https://github.com/pimoroni/pimoroni-pico
				
				
				
			
		
			
				
	
	
		
			373 wiersze
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			373 wiersze
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
#include <stdio.h>
 | 
						|
#include <math.h>
 | 
						|
#include <cstdint>
 | 
						|
 | 
						|
#include "pico/stdlib.h"
 | 
						|
 | 
						|
#include "plasma2040.hpp"
 | 
						|
 | 
						|
#include "common/pimoroni_common.hpp"
 | 
						|
#include "rgbled.hpp"
 | 
						|
#include "button.hpp"
 | 
						|
 | 
						|
/*
 | 
						|
****LED STRIP STACKER GAME****
 | 
						|
Button a Begins game
 | 
						|
 | 
						|
push button when the red and yellow leds cross each other.
 | 
						|
see how far you get...
 | 
						|
by Gee 'Rabid Inventor' Bartlett
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
using namespace pimoroni;
 | 
						|
using namespace plasma;
 | 
						|
 | 
						|
// Set how many LEDs you have
 | 
						|
const uint N_LEDS = 40;
 | 
						|
const uint REFRESH_DELAY = 100;
 | 
						|
 | 
						|
// Pick *one* LED type by uncommenting the relevant line below:
 | 
						|
 | 
						|
// APA102-style LEDs with Data/Clock lines. AKA DotStar
 | 
						|
//APA102 led_strip(N_LEDS, pio0, 0, plasma2040::DAT, plasma2040::CLK);
 | 
						|
 | 
						|
// WS28X-style LEDs with a single signal line. AKA NeoPixel
 | 
						|
// by default the WS2812 LED strip will be 400KHz, RGB with no white element
 | 
						|
//WS2812 led_strip(N_LEDS, pio0, 0, plasma2040::DAT);
 | 
						|
 | 
						|
//Uncomment for WS2812 with RGBW running at 800KHz
 | 
						|
WS2812 led_strip(N_LEDS, pio0, 0, plasma2040::DAT, 800000, true);
 | 
						|
 | 
						|
Button button_a(plasma2040::BUTTON_A, Polarity::ACTIVE_LOW, 50);
 | 
						|
Button button_b(plasma2040::BUTTON_B, Polarity::ACTIVE_LOW, 50);
 | 
						|
RGBLED led(plasma2040::LED_R, plasma2040::LED_G, plasma2040::LED_B);
 | 
						|
 | 
						|
 | 
						|
class playfield_object{
 | 
						|
    public:
 | 
						|
    uint8_t position = 0;
 | 
						|
    uint8_t length = 0;
 | 
						|
    int move_direction = 1;
 | 
						|
    uint8_t speed = 0;
 | 
						|
    uint8_t colour_R = 0;
 | 
						|
    uint8_t colour_G = 0;
 | 
						|
    uint8_t colour_B = 0;
 | 
						|
    int is_present_at(uint8_t test_position){
 | 
						|
        int ret = 0;
 | 
						|
        if (test_position >= position){
 | 
						|
            if (test_position <= position + length){
 | 
						|
                ret = 1;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return ret;
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
class levels{
 | 
						|
    public:
 | 
						|
    uint8_t player_speed = 0;
 | 
						|
    uint8_t player_speed_increase_rate = 0;
 | 
						|
    bool moving_target = false;
 | 
						|
    uint8_t target_speed = 0;
 | 
						|
    uint8_t target_speed_increase_rate = 0;
 | 
						|
    bool moving_playfield = false;
 | 
						|
    uint8_t playfield_speed = 0;
 | 
						|
    uint8_t playfield_speed_increase_rate = 0;
 | 
						|
};
 | 
						|
 | 
						|
class StackerGame{
 | 
						|
    public:
 | 
						|
    enum states{
 | 
						|
        ATTRACT_MODE,
 | 
						|
        GAME_STARTED
 | 
						|
    };
 | 
						|
    levels begining_level;
 | 
						|
    uint8_t playfield_width;
 | 
						|
    int current_step = 0;
 | 
						|
    states game_state = ATTRACT_MODE;
 | 
						|
    int score = 0;
 | 
						|
    uint8_t game_speed = 0;
 | 
						|
    playfield_object player;
 | 
						|
    playfield_object target;
 | 
						|
    playfield_object left_wall;
 | 
						|
    playfield_object right_wall;
 | 
						|
 | 
						|
    void start(levels game_level);
 | 
						|
    void reset(levels game_level);
 | 
						|
    void game_step();
 | 
						|
    void advance_round();
 | 
						|
    void stop();
 | 
						|
};
 | 
						|
 | 
						|
void StackerGame::start(levels game_level){
 | 
						|
    game_state = ATTRACT_MODE;
 | 
						|
    begining_level = game_level;
 | 
						|
    playfield_width = N_LEDS;
 | 
						|
    player.position = 5;
 | 
						|
    player.length = 10;
 | 
						|
    target.position = 15;
 | 
						|
    target.length = 10;
 | 
						|
    left_wall.position = 0;
 | 
						|
    left_wall.length = 3;
 | 
						|
    right_wall.position = playfield_width - left_wall.length;
 | 
						|
    right_wall.length = left_wall.length;
 | 
						|
    player.speed = begining_level.player_speed;
 | 
						|
    target.speed = begining_level.target_speed;
 | 
						|
 | 
						|
    //object colours
 | 
						|
    player.colour_R = 0;
 | 
						|
    player.colour_B = 0;
 | 
						|
    player.colour_G = 50;
 | 
						|
 | 
						|
    target.colour_R = 50;
 | 
						|
    target.colour_G = 50;
 | 
						|
    target.colour_B = 0;
 | 
						|
 | 
						|
    left_wall.colour_R = 0;
 | 
						|
    left_wall.colour_G = 0;
 | 
						|
    left_wall.colour_B = 50;
 | 
						|
 | 
						|
    right_wall.colour_R = 0;
 | 
						|
    right_wall.colour_G = 0;
 | 
						|
    right_wall.colour_B = 50;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void StackerGame::reset(levels game_level){
 | 
						|
    begining_level = game_level;
 | 
						|
    playfield_width = N_LEDS;
 | 
						|
    player.position = 5;
 | 
						|
    player.length = 10;
 | 
						|
    target.position = 15;
 | 
						|
    target.length = 10;
 | 
						|
    left_wall.position = 0;
 | 
						|
    left_wall.length = 3;
 | 
						|
    right_wall.position = playfield_width - left_wall.length;
 | 
						|
    right_wall.length = left_wall.length;
 | 
						|
    player.speed = begining_level.player_speed;
 | 
						|
    target.speed = begining_level.target_speed;
 | 
						|
    begining_level.moving_target = false;
 | 
						|
 | 
						|
    //object colours
 | 
						|
    player.colour_R = 0;
 | 
						|
    player.colour_B = 0;
 | 
						|
    player.colour_G = 50;
 | 
						|
 | 
						|
    target.colour_R = 50;
 | 
						|
    target.colour_G = 50;
 | 
						|
    target.colour_B = 0;
 | 
						|
 | 
						|
    left_wall.colour_R = 0;
 | 
						|
    left_wall.colour_G = 0;
 | 
						|
    left_wall.colour_B = 50;
 | 
						|
 | 
						|
    right_wall.colour_R = 0;
 | 
						|
    right_wall.colour_G = 0;
 | 
						|
    right_wall.colour_B = 50;
 | 
						|
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void StackerGame::stop(){
 | 
						|
    sleep_ms(500);
 | 
						|
    game_state = ATTRACT_MODE;
 | 
						|
    reset(begining_level);
 | 
						|
    
 | 
						|
    
 | 
						|
    
 | 
						|
}
 | 
						|
 | 
						|
void StackerGame::advance_round(){
 | 
						|
 | 
						|
    player.speed = player.speed + begining_level.player_speed_increase_rate;
 | 
						|
    
 | 
						|
    if (player.speed > 240){ //higher level stuff
 | 
						|
        begining_level.moving_target = true;
 | 
						|
        player.speed = begining_level.player_speed;
 | 
						|
        target.speed = target.speed + begining_level.target_speed_increase_rate;
 | 
						|
    }
 | 
						|
    
 | 
						|
    
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void StackerGame::game_step(){
 | 
						|
    current_step++;
 | 
						|
 | 
						|
    bool a = button_a.read();
 | 
						|
 | 
						|
    if (game_state == GAME_STARTED){
 | 
						|
        if (a){
 | 
						|
            if (player.position == target.position)
 | 
						|
            {
 | 
						|
            advance_round();
 | 
						|
            }
 | 
						|
            else if (player.position < target.position ){
 | 
						|
                if (player.position + player.length >= target.position){
 | 
						|
                    target.length = target.length - (target.position - player.position);
 | 
						|
                    player.length = target.length;
 | 
						|
                    sleep_ms(200);
 | 
						|
                    advance_round();
 | 
						|
 | 
						|
                }
 | 
						|
                else{
 | 
						|
                    stop();
 | 
						|
                }
 | 
						|
            }
 | 
						|
            
 | 
						|
            else if (player.position > target.position){
 | 
						|
                if(player.position < target.position + target.length){
 | 
						|
                    
 | 
						|
                    target.length = target.length - (player.position - target.position);
 | 
						|
                    target.position = player.position;
 | 
						|
                    player.length = target.length;
 | 
						|
                    sleep_ms(200);
 | 
						|
                    advance_round();
 | 
						|
 | 
						|
                }
 | 
						|
                else{
 | 
						|
                    stop();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
            
 | 
						|
    
 | 
						|
        
 | 
						|
            
 | 
						|
            // aminate player and target ingame
 | 
						|
            if (player.position + player.length >= right_wall.position){
 | 
						|
                player.move_direction = -1;
 | 
						|
            }
 | 
						|
            if (player.position <= left_wall.position + left_wall.length){
 | 
						|
                player.move_direction = 1;
 | 
						|
            }
 | 
						|
            if (current_step % (254 - player.speed) == 0){
 | 
						|
                player.position += player.move_direction;
 | 
						|
            }
 | 
						|
 | 
						|
 | 
						|
            if (begining_level.moving_target){
 | 
						|
                if (target.position + target.length >= right_wall.position){
 | 
						|
                    target.move_direction = -1;
 | 
						|
                }
 | 
						|
                if (target.position <= left_wall.position + left_wall.length){
 | 
						|
                    target.move_direction = 1;
 | 
						|
                }
 | 
						|
                if (current_step % (254 - target.speed) == 0){
 | 
						|
                    target.position += target.move_direction;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        
 | 
						|
    }
 | 
						|
 | 
						|
    else if (game_state == ATTRACT_MODE){
 | 
						|
 | 
						|
        if (a){
 | 
						|
            game_state = GAME_STARTED;
 | 
						|
            reset(begining_level);
 | 
						|
            sleep_ms(2000);
 | 
						|
        }
 | 
						|
        
 | 
						|
        // aminate player and target attract mode
 | 
						|
        if (player.position + player.length >= right_wall.position){
 | 
						|
            player.move_direction = -1;
 | 
						|
        }
 | 
						|
        if (player.position <= left_wall.position + left_wall.length){
 | 
						|
            player.move_direction = 1;
 | 
						|
        }
 | 
						|
        if (current_step % (254 - 150) == 0){
 | 
						|
            player.position += player.move_direction;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        
 | 
						|
        if (target.position + target.length >= right_wall.position){
 | 
						|
            target.move_direction = -1;
 | 
						|
        }
 | 
						|
        if (target.position <= left_wall.position + left_wall.length){
 | 
						|
            target.move_direction = 1;
 | 
						|
        }
 | 
						|
        if (current_step % (254 - 50) == 0){
 | 
						|
            target.position += target.move_direction;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
    
 | 
						|
 | 
						|
    }
 | 
						|
    
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
int main() {
 | 
						|
    stdio_init_all();
 | 
						|
 | 
						|
    led_strip.start(60);
 | 
						|
 | 
						|
    
 | 
						|
    StackerGame stacker; // create instance of stacker game
 | 
						|
 | 
						|
    //create level instance this is where you can adjust beginning dificulty
 | 
						|
    levels level_1;
 | 
						|
    level_1.player_speed = 70;
 | 
						|
    level_1.player_speed_increase_rate = 10;
 | 
						|
    level_1.moving_target = false;
 | 
						|
    level_1.target_speed = 20;
 | 
						|
    level_1.target_speed_increase_rate = 10;
 | 
						|
 | 
						|
    stacker.start(level_1);
 | 
						|
 | 
						|
    
 | 
						|
 | 
						|
 | 
						|
    while (true) {
 | 
						|
        //do game loop
 | 
						|
        stacker.game_step();
 | 
						|
 | 
						|
        if (stacker.game_state == stacker.ATTRACT_MODE){
 | 
						|
            bool a = button_a.read();
 | 
						|
            if (a){
 | 
						|
                
 | 
						|
                stacker.game_state = stacker.GAME_STARTED;
 | 
						|
                stacker.start(level_1);
 | 
						|
                sleep_ms(2000);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        
 | 
						|
        
 | 
						|
        // leds update routine 
 | 
						|
        for(auto i = 0u; i < led_strip.num_leds; ++i) {
 | 
						|
 | 
						|
            if (stacker.target.is_present_at(i)){
 | 
						|
                led_strip.set_rgb(i, stacker.target.colour_R, stacker.target.colour_G, stacker.target.colour_B);
 | 
						|
                
 | 
						|
                if (stacker.player.is_present_at(i)){
 | 
						|
                    led_strip.set_rgb(i, stacker.target.colour_R - stacker.player.colour_R, 
 | 
						|
                                         stacker.target.colour_G - stacker.player.colour_G,
 | 
						|
                                         stacker.target.colour_B - stacker.player.colour_B);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else if (stacker.player.is_present_at(i)){
 | 
						|
                led_strip.set_rgb(i, stacker.player.colour_R, stacker.player.colour_G, stacker.player.colour_B);
 | 
						|
            }
 | 
						|
            else if (stacker.left_wall.is_present_at(i)){
 | 
						|
                led_strip.set_rgb(i, stacker.left_wall.colour_R, stacker.left_wall.colour_G, stacker.left_wall.colour_B);
 | 
						|
            }
 | 
						|
 | 
						|
            else if (stacker.right_wall.is_present_at(i)){
 | 
						|
                led_strip.set_rgb(i, stacker.right_wall.colour_R, stacker.right_wall.colour_G, stacker.right_wall.colour_B);
 | 
						|
            }
 | 
						|
            else{
 | 
						|
                led_strip.set_rgb(i, 0, 0, 0);
 | 
						|
            }
 | 
						|
            
 | 
						|
            
 | 
						|
        }
 | 
						|
            
 | 
						|
        // Sleep time controls the rate at which the LED buffer is updated
 | 
						|
        // but *not* the actual framerate at which the buffer is sent to the LEDs
 | 
						|
        sleep_ms(1);
 | 
						|
    }
 | 
						|
}
 |