С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Ну, может использовать тот же счетчик? В момент прыжка вычисляем смещение в одно знакоместо, на счет 3 смещение на 0,5 знакоместа, такты 6,7 - зависает персонаж, и потом меняем вектор движения и также обратно, сначала на 0,5 знакоместа, потом на 1, пока не встретится препятствие. Я когда питоном баловался, так примерно делал. Но то там...
Надо какую-то функцию к счетчику прикручивать, либо синус, либо параболу, либо сплайн. Так в современных игровых движках анимация устроена, линейное перемещение можно заменить. Но все равно не очень понятно, как себя должен вести спрайт при двойном прыжке. Попробую с импульсом подружиться.
По поводу еще одной идеи для игры. Баскетбол в одну корзину. Но мяч можно держать в воздухе нажимая пробел - мяч получит дополнительный импульс при нажатии. На яндекс играх увидел)
не забывай, что у тебя крайне неторопливый процессор, а потому высчитывать движение по формуле может быть не так практично, чем если заложить готовый алгоритм движения. В качестве примера можно рассмотреть Super Mario для nes - там у процессора всего три регистра (правда два из них индексные), но прыжок выглядит довольно плавно и, как мне думается никаких сложных вычислений там не сделать. Хотя, конечно, видеочип там тоже многое сглаживает. А частота то с РК вроде как одна.
Значения синуса с удобным шагом можно в таблицу записать, и брать оттуда готовое значение, чтобы не считать. Я так на ардуине синусоиду и другие формы сигнала генерил через PWM.
ну в общем, несколько спрайтов. Правда выглядят грубовато в стандартном режиме РК, а вот в 44*7 может и ничего будет. Надо еще учитывать что спрайты в формате РК будут несколько худее, чем на рисунке. Формат изображения 90*50 пикселей. Мне в gimp нормально работать, так что масштабированием я не занимался. В фотошопе тож нормально будет видно при увеличении, или в paint.net. Содрано с "CRACKY mini" (TANDY200)
https://disk.yandex.ru/i/mZzUkrh5zQANVA
Если мелковато - извините. Но суть все равно ясна.
Hammer (14.01.2024)
Вот таблица для синуса, которую я использовал для генерации 8-ми битного звука:
Смысл такой, линейная позиция - это индекс для таблицы. Например, если у нас весь прыжок описывается значением от 0 до 7, то значение нужно отмасштабировать до диапазона таблицы. Значит делаем побитовый сдвиг линейного значения влево 5 раз. А полученную из таблицы цифру наоборот сдвигаем вправо. Сдвиг влево - это умножение на два, сдвиг вправо - деление на два. Таким образом подбираем нужные коэффициенты. Работает быстро, без шума и пыли )Код:sine: db $00, $00, $00, $00, $01, $01, $01, $02, db $02, $03, $04, $05, $05, $06, $07, $09, db $0A, $0B, $0C, $0E, $0F, $11, $12, $14, db $15, $17, $19, $1B, $1D, $1F, $21, $23, db $25, $28, $2A, $2C, $2F, $31, $34, $36, db $39, $3B, $3E, $41, $43, $46, $49, $4C, db $4F, $52, $55, $58, $5A, $5D, $61, $64, db $67, $6A, $6D, $70, $73, $76, $79, $7C, db $80, $83, $86, $89, $8C, $8F, $92, $95, db $98, $9B, $9E, $A2, $A5, $A7, $AA, $AD, db $B0, $B3, $B6, $B9, $BC, $BE, $C1, $C4, db $C6, $C9, $CB, $CE, $D0, $D3, $D5, $D7, db $DA, $DC, $DE, $E0, $E2, $E4, $E6, $E8, db $EA, $EB, $ED, $EE, $F0, $F1, $F3, $F4, db $F5, $F6, $F8, $F9, $FA, $FA, $FB, $FC, db $FD, $FD, $FE, $FE, $FE, $FF, $FF, $FF, db $FF, $FF, $FF, $FF, $FE, $FE, $FE, $FD, db $FD, $FC, $FB, $FA, $FA, $F9, $F8, $F6, db $F5, $F4, $F3, $F1, $F0, $EE, $ED, $EB, db $EA, $E8, $E6, $E4, $E2, $E0, $DE, $DC, db $DA, $D7, $D5, $D3, $D0, $CE, $CB, $C9, db $C6, $C4, $C1, $BE, $BC, $B9, $B6, $B3, db $B0, $AD, $AA, $A7, $A5, $A2, $9E, $9B, db $98, $95, $92, $8F, $8C, $89, $86, $83, db $80, $7C, $79, $76, $73, $70, $6D, $6A, db $67, $64, $61, $5D, $5A, $58, $55, $52, db $4F, $4C, $49, $46, $43, $41, $3E, $3B, db $39, $36, $34, $31, $2F, $2C, $2A, $28, db $25, $23, $21, $1F, $1D, $1B, $19, $17, db $15, $14, $12, $11, $0F, $0E, $0C, $0B, db $0A, $09, $07, $06, $05, $05, $04, $03, db $02, $02, $01, $01, $01, $00, $00, $00
Ну так вот... Немного распишу как делать задержки в общем цикле.
До этого создаем 2 массива, первый - координаты прыжка, второй задержка между итерациями.Код:void dino_core(void) { if (dino.jump !=1) // если не прыгаем { put_sprite_3 = dino.dino_ptr[dino.AnimFrame]; // отрисуем текущий спрайт put_sprite(dino.x,dino.y); // выведем по координатам if (dino.AnimFrame==0) dino.AnimFrame = 1; else dino.AnimFrame = 0; // шевелим ногами (меняем спрайты) } else { jump_delay--; // уменьшаем задержку прыжка if (jump_delay == 0) {// достигла 0 jump_delay = di_jmp_dl[dino_jump_pointer];// обновим задержку с нового места массива put_sprite_3 = dino_empty;// пустой спрайт put_sprite(dino.x,dino.y);// затрем предыдущее состояние dino.y = dino_jump[dino_jump_pointer];// обновим новую координату по y put_sprite_3 = dino.dino_ptr[dino.AnimFrame];// обновим спрайт put_sprite(dino.x,dino.y); // отрисуем в экран if (dino_jump_pointer!=8){ // достигли конца координат прыжка и его задержки? dino_jump_pointer++;// если нет то следующий } else { dino.jump =0; //если да то снимаем флаг прыжка dino.busy =0;// снимаем флаг запрета опроса кнопок } } } }
unsigned char dino_jump[9] = {16,12,11,8,8,8,14,16,18};
unsigned char di_jmp_dl[9] = { 1, 2, 2,3,7,5, 3, 2, 1};
Как видно, координата 8 (что посерединке, 4 элемент массива) самая затяжная (задержка 7 циклов) ибо является переломной в физике .. типа дальше падаем вниз.
Да, координаты по у в рк чем выше экран тем ближе к 0, и еще... запустив пример, вы увидите почему задержка в циклах такая маленькая. Игровой процесс оброс кактусами скроллом прыжками и прочим... задержки минимальны... увы проц совсем слаб.
что такое 1 цикл? а вот...
сие есть один цикл. Еще добавится птеродактиль и опрос на коллизии с птеродактилем и кактусами. Задержку придется еще больше занизить. Помимо всего еще будет отрисовка очков и может быть смена дня ночи.... Вот поэтому я и сделал пальмиру. Там хотя бы можно выпаять кварц штатный 16 мгц и впаять хотя бы 18, и можно спокойно играть в новые игры.Код:while(1) { check_player(); cactus_check(); waitHorzSync(); scroll(); cactus_core(); dino_core(); }
https://cloud.mail.ru/public/PqL6/8i1S5L45h Загружайте смотрите, принимаются замечания. По сути основная часть игры готова - осталась ерунда.
Кстати да, о чем писалось выше, обратите внимание - кактус асинхронен скролу земли... Все просто. Кому интересно - выложу движок сюда . Вместе обмусолим , вместе допилим, вместе продвинем в массовость.
- - - Добавлено - - -
Раз уж добрался до компа распишу немного больше полностью по динозаврику моменты.
самое интересное - наверное структура самого динозаврикаКод:void check_player(void) { uint8_t kb=255; if (dino.busy==1) return; // ядро занято отрисовкой и нет смысла жать кнопки и их отрабатывать kb=0xff; kb=key_scan(0xfd);// опросим клавиатуру if (kb==223) //жмем прыжок { dino.dino_ptr = Dino[0]; // набор спрайтов для летящего динозаврика (тут статика) dino.AnimFrame=0;// но начнем с начального тайла dino.jump = 1; // сообщение ядру что мы прыгаем dino.busy = 1; // сообщение этой функции в дальнейшем что мы заняты jump_delay = 1; // костыль (как же без него) dino_jump_pointer = 0;// указатель на массивы координат Y и задержки } if (kb==127)// жмем вниз { put_sprite_3 = dino_empty; // todo в разработке put_sprite(dino.x,dino.y); dino.dino_ptr = Dino[2]; } if (kb==239)//run left // немного от оригинала отошел - бежим влево { dino.x-=1; if (dino.x<left_x) dino.x=left_x; // ограничение } if (kb==191) // бежим вправо { dino.x+=1; if (dino.x>right_x) dino.x=right_x; } //Мы ничего не делаем. Будем просто бежать if (kb==255) // нет действий от пользователя { if (dino.dino_ptr != Dino[1])dino.dino_ptr = Dino[1]; // сменим набор спрайтов на бег } }
typedef struct
{
unsigned char busy;
unsigned char jump; //
unsigned char y; //
unsigned char x;
unsigned char **dino_ptr; // выбор спрайтов
unsigned char AnimFrame; // номер выводимого спрайта
}dino_t;
предпоследний указатель немного сложен...да, потому что указатель на массивы
unsigned char **Dino[] = {Dino_stay , Dino_run, Dino_duck,};
а в свою очередь содержимое массива выше это....
unsigned char *Dino_stay[] =
{
dino1,
dino1,
};
unsigned char *Dino_run[] =
{
dino2,
dino3,
};
... где например...
Это уже массив самого спрайта.Код:unsigned char dino1[122] = { 10,12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x07, 0x17, 0x17, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x13, 0x03, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x17, 0x17, 0x03, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x16, 0x17, 0x17, 0x17, 0x14, 0x00, 0x00, 0x00, 0x00, 0x17, 0x15, 0x16, 0x17, 0x17, 0x17, 0x17, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x17, 0x17, 0x17, 0x17, 0x17, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x17, 0x17, 0x17, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x13, 0x02, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00 };
Стоит отметить, что такая реализация указателей массивов и структур очень неплохо переваривается самим z88dk. Исполняемый код в таком стиле создается максимально быстрым.
Радио86 рк (Пальмира), Электроника кр04, Поиск 1
У меня и оба экрана заработали, и функция синуса. Всё быстро бегает, я вполне доволен. Ещё несколько косяков уберу и будет новая демка.
Но! С двойным экраном есть две фичи:
1. Пока мы отображаем один экран, а рисуем на втором, спрайт может поменять свою позицию. Если под спрайтом фон не перерисовывать, то стирать спрайт тоже придется сначала на старом экране, потом на новом. Иначе будет мерцание.
2. Я отрисовываю звезды не каждый цикл, а через раз. И от этого они попадают всегда на чётный экран. Из-за этого звёзды мерцают. Не хочется их в общий цикл ставить, но наверное придётся.
Теперь надо придумывать, как быстро коллизии считать.
Вот ещё интересная графика:
Oleg N. Cher (15.01.2024), parallelno (16.01.2024), tnt23 (17.01.2024)
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)