Pour info, la rocket a une taille de 14x26 (dans l'image d'origine, quand la rocket est allongée) et quand j'ai modifié l'image d'origine pour qu'elle soit debout, ca affichait seulement les 14 premières lignes de l'image.
Voici le code:
- Code: Select all
#include <keypadc.h>
#include <graphx.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <debug.h>
#include <tice.h>
/* Include the converted graphics file */
#include "gfx/gfx.h"
/* Include the external tilemap data */
extern unsigned char tilemap_map[];
/* Tilemap defines */
#define TILE_WIDTH 16
#define TILE_HEIGHT 16
#define TILEMAP_WIDTH 20
#define TILEMAP_HEIGHT 15
#define TILEMAP_DRAW_WIDTH 20
#define TILEMAP_DRAW_HEIGHT 15
#define Y_OFFSET 0 // CAMERA_X
#define X_OFFSET 0 // CAMERA_Y
#define SPEED 2
#define DIAGONAL_SPEED (SPEED * 0.707) // Speed reduction for diagonal movement
typedef struct {
int x, y;
float dx, dy;
bool active;
} Rocket;
/* Constants */
#define MAX_ROCKETS 10
#define ROCKET_SPEED 2.5
#define COOLDOWN_TIME 30 // 0.5 seconds as RTC counts at 60Hz
/* Rocket list */
Rocket rockets[MAX_ROCKETS] = {0};
int rocket_cooldown = 0;
/* Function to add a new rocket */
void add_rocket(int start_x, int start_y) {
for (int i = 0; i < MAX_ROCKETS; i++) {
if (!rockets[i].active) {
rockets[i].x = start_x;
rockets[i].y = start_y;
float angle = atan2f(0 - start_y, 0 - start_x); // Calculate angle towards (0,0)
rockets[i].dx = ROCKET_SPEED * cosf(angle);
rockets[i].dy = ROCKET_SPEED * sinf(angle);
rockets[i].active = true;
rocket_cooldown = COOLDOWN_TIME; // Start cooldown
break;
}
}
}
/* Function to update rockets */
void update_rockets(gfx_tilemap_t *tilemap) {
for (int i = 0; i < MAX_ROCKETS; i++) {
if (rockets[i].active) {
rockets[i].x += rockets[i].dx;
rockets[i].y += rockets[i].dy;
// Check for collisions with map boundaries or tiles 1, 2, 6
unsigned int tile_x = rockets[i].x / TILE_WIDTH;
unsigned int tile_y = rockets[i].y / TILE_HEIGHT;
if (rockets[i].x < 0 || rockets[i].y < 0 ||
rockets[i].x >= TILEMAP_WIDTH * TILE_WIDTH || rockets[i].y >= TILEMAP_HEIGHT * TILE_HEIGHT ||
*gfx_TilePtrMapped(tilemap, tile_x, tile_y) == 1 ||
*gfx_TilePtrMapped(tilemap, tile_x, tile_y) == 2 ||
*gfx_TilePtrMapped(tilemap, tile_x, tile_y) == 6) {
rockets[i].active = false; // Deactivate rocket on collision
}
}
}
}
/* Function to draw rockets */
void draw_rockets(void) {
for (int i = 0; i < MAX_ROCKETS; i++) {
if (rockets[i].active) {
int angle = atan2f(0 - rockets[i].y, 0 - rockets[i].x) * 128 / M_PI; // Convert angle to gfx 256 position
gfx_RotatedScaledTransparentSprite_NoClip(rocket, rockets[i].x, rockets[i].y, angle, 64);
}
}
}
/* Function to check if a tile is walkable (0 is walkable, 1/2/6 are obstacles) */
bool is_walkable(unsigned int tile_x, unsigned int tile_y, gfx_tilemap_t *tilemap) {
if (tile_x < 0 || tile_x >= TILEMAP_WIDTH || tile_y < 0 || tile_y >= TILEMAP_HEIGHT) {
return false; // Out of bounds
}
uint8_t block_mapped = *gfx_TilePtrMapped(tilemap, tile_x, tile_y);
return !(block_mapped == 1 || block_mapped == 2 || block_mapped == 6);
}
int main(void)
{
unsigned int x_offset = 0;
unsigned int y_offset = 0;
gfx_tilemap_t tilemap;
/* Initialize the tilemap structure */
tilemap.map = tilemap_map;
tilemap.tiles = tileset_tiles;
tilemap.type_width = gfx_tile_16_pixel;
tilemap.type_height = gfx_tile_16_pixel;
tilemap.tile_height = TILE_HEIGHT;
tilemap.tile_width = TILE_WIDTH;
tilemap.draw_height = TILEMAP_DRAW_HEIGHT;
tilemap.draw_width = TILEMAP_DRAW_WIDTH;
tilemap.height = TILEMAP_HEIGHT;
tilemap.width = TILEMAP_WIDTH;
tilemap.y_loc = Y_OFFSET;
tilemap.x_loc = X_OFFSET;
unsigned int player_x = TILEMAP_DRAW_WIDTH * TILE_WIDTH / 2;
unsigned int player_y = TILEMAP_DRAW_HEIGHT * TILE_HEIGHT / 2 + 8;
/* Buffers for flipping sprites */
gfx_sprite_t *flipped_side = gfx_MallocSprite(15, 20); // Allocate memory for the flipped sprite
gfx_sprite_t *player_sprite = brock_down; // Default sprite (down)
/* Initialize graphics drawing */
gfx_Begin();
/* Set the palette */
gfx_SetPalette(global_palette, sizeof_global_palette, 0);
gfx_SetColor(0);
gfx_SetTextFGColor(1);
gfx_SetTextBGColor(0);
/* Draw to buffer to avoid tearing */
gfx_SetDrawBuffer();
/* Set monospace font with width of 8 */
gfx_SetMonospaceFont(8);
gfx_SetTransparentColor(0);
/* Wait for the enter key to quit */
do
{
kb_key_t arrows;
kb_key_t keys;
/* Scan the keypad */
kb_Scan();
arrows = kb_Data[7]; // Check arrow keys (7th row of kb_Data)
keys = kb_Data[1];
/* Handle key presses to move the tilemap */
bool moved = false;
float move_x = 0, move_y = 0;
/* Check directional inputs and update player sprite */
if (arrows & kb_Down) {
move_y += SPEED;
player_sprite = brock_down; // Change sprite to down
}
if (arrows & kb_Up) {
move_y -= SPEED;
player_sprite = brock_up; // Change sprite to up
}
if (arrows & kb_Right) {
move_x += SPEED;
player_sprite = brock_side; // Change sprite to right
}
if (arrows & kb_Left) {
move_x -= SPEED;
gfx_FlipSpriteY(brock_side, flipped_side); // Flip sprite for left movement
player_sprite = flipped_side; // Set flipped sprite for left direction
}
/* If moving diagonally, normalize speed */
if (move_x != 0 && move_y != 0) {
move_x *= DIAGONAL_SPEED / SPEED;
move_y *= DIAGONAL_SPEED / SPEED;
}
/* Calculate the new positions */
unsigned int new_player_x = player_x + (int)move_x;
unsigned int new_player_y = player_y + (int)move_y;
/* Check if the movement is valid (collision detection) */
if (move_y > 0) { // Moving down
unsigned int tile_y = (new_player_y + 15) / TILE_HEIGHT; // bottom side
unsigned int tile_x_left = player_x / TILE_WIDTH; // bottom-left corner
unsigned int tile_x_right = (player_x + 15) / TILE_WIDTH; // bottom-right corner
if (is_walkable(tile_x_left, tile_y, &tilemap) && is_walkable(tile_x_right, tile_y, &tilemap)) {
player_y = new_player_y;
moved = true;
}
} else if (move_y < 0) { // Moving up
unsigned int tile_y = new_player_y / TILE_HEIGHT; // top side
unsigned int tile_x_left = player_x / TILE_WIDTH; // top-left corner
unsigned int tile_x_right = (player_x + 15) / TILE_WIDTH; // top-right corner
if (is_walkable(tile_x_left, tile_y, &tilemap) && is_walkable(tile_x_right, tile_y, &tilemap)) {
player_y = new_player_y;
moved = true;
}
}
if (move_x > 0) { // Moving right
unsigned int tile_x = (new_player_x + 15) / TILE_WIDTH; // right side
unsigned int tile_y_top = player_y / TILE_HEIGHT; // top-right corner
unsigned int tile_y_bottom = (player_y + 15) / TILE_HEIGHT; // bottom-right corner
if (is_walkable(tile_x, tile_y_top, &tilemap) && is_walkable(tile_x, tile_y_bottom, &tilemap)) {
player_x = new_player_x;
moved = true;
}
} else if (move_x < 0) { // Moving left
unsigned int tile_x = new_player_x / TILE_WIDTH; // left side
unsigned int tile_y_top = player_y / TILE_HEIGHT; // top-left corner
unsigned int tile_y_bottom = (player_y + 15) / TILE_HEIGHT; // bottom-left corner
if (is_walkable(tile_x, tile_y_top, &tilemap) && is_walkable(tile_x, tile_y_bottom, &tilemap)) {
player_x = new_player_x;
moved = true;
}
}
if (keys & kb_2nd && rocket_cooldown == 0) {
add_rocket(player_x, player_y);
}
/* Update cooldown */
if (rocket_cooldown > 0) {
rocket_cooldown--;
}
update_rockets(&tilemap);
/* Draw tilemap first */
gfx_Tilemap_NoClip(&tilemap, x_offset, y_offset);
/* Draw player sprite */
gfx_TransparentSprite(player_sprite, player_x, player_y - 4);
draw_rockets();
/* Swap draw buffer to update the screen */
gfx_SwapDraw();
} while (kb_Data[6] != kb_Annul); // Exit on Annul key (6th row of kb_Data)
/* End graphics drawing */
gfx_End();
return 0;
}