По правде, я ненавижу многие нововведения ГМС2, равно как и ГМС1, но с этим приходится работать, чтобы выходить на последние платформы, включая HTML5, Android, iOS, Xbox One, PS4 и Nintendo Switch. А скомпилированное в ГМ8.1 работает на Windows XP прекрасно, т. к. он ещё и сам шёл на Windows XP. Найди где-нибудь в интернете, скажем тут, и пробуй. Если что непонятно, проконсультирую.
Чтобы вычислить? Ну как в калькуляторе нужно сначала вбить первое число, иначе с чем работать? Надо его в ячейку записать, это я и обозначил как "загрузить".
Это инициализация переменной
Нет, в переменной к этому моменту уже есть нужное нам число. Мы загружаем это число ИЗ переменной в регистр - потому что только в регистре могут происходить вычисления. Переменная это просто что-то где-то в оперативной памяти, тогда как регистр - физически существующая (в реальном мире, а не в магическом мире программирования) в процессоре (да, в той квадратной штуке вставленной в материнскую плату твоего компьютера) ячейка куда попадает нужное количество электронов, чтобы представлять собой нужное число.
Плюс тут есть вообще функции?
Есть, без них никуда.
goto
Хорошие новости - есть. Плохие новости - без goto в ассемблере невозможно сделать цикл for, да и никакой другой цикл тоже. Потому что цикл в нём делается так:
mov cx, 10 ;загружаем в счётчик число 10
loop: ;это просто метка для goto
тело цикла
dec cx ;отнять от счётчика единицу, потому что цикл прошёл
jnz loop ;это равносильно "если cx не стало равно нулю, goto loop"
Вместо 10 можно загрузить любую переменную.
В си-подобном коде это было бы:
for (i=0; i<10; i++)
{
тело цикла
}
Есть ли тут простейшие if и for?
Нет и нет. Про for я уже показал выше, а всё что ты пишешь в if например так:
if ((this) && (that))
1 //действия если условие верно
else
2 //действия если условие неверно
Должно вычисляться в ассемблере поштучно и по порядку:
mov ax, this ;загружаем в регистр первое условие
and ax, that ;делаем логическую операцию "И" с загруженным и вторым условиями
cmp ax, TRUE ;сравниваем результат с "ИСТИНОЙ"
je ok ;если оба условия соблюдены, дальше идём к метке ok (goto ok)
jnz not_ok ;иначе к метке not_ok
ok: 1 ;действия если условие верно
goto end_of_if ;переход в конец
not_ok: 2 ;действия если условие неверно
end_of_if: ;конец
вряд ли я смогу даже простой "Hello World" для NES на ассемблере написать)
Важный факт: "Hello World" это программа, которую никто и никогда не пишет с нуля. Все Хэллоу Ворлды копируются с уже существующих предыдущих, поэтому задача состоит в копировании, а не в придумывании всех заклинаний, обрамляющих то что программисту на самом деле нужно от компьютера. Я имею в виду, если программа должна выводить одну строку, то она и должна состоять из одной строки. А на практике на том же C# тебе нужно писать:
using System.Text;
using что-то там ещё;
class HelloWorld
{
static void Main()
{
тут наконец вывод текста
}
}
Да, в современных IDE это всё сразу в шаблоне пустого проекта, но сколько мусора приходится видеть на экране, и сколько раз вычислять нужное среди ненужного?
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
message:
db 'Hello, World', 10, 0
Я это к чему - чтобы освоить язык и/или платформу, нужно просто работать по уже существующим примерам. Ты себя просто недооцениваешь, другое дело что мотивация работать с ассемблером будет неминуемо падать, учитывая сколько времени требуется на написание программы на нём. И в целом рекомендации на нём делать игры я дать не имею оснований.
$animation.play("die") #проигрываем анимацию смерти
yield($animation, "animation_finished") #ждем завершения анимации
queue_free() #удаляем объект ко всем чертям собачьим
Можно по имени переключать, положи их в одну директорию, и делай get_tree().change_scene("res://path/to/scene.tscn"), где путь склеиваешь из постоянной директории и переменного названия уровня.
Тема гаминатора: "Не то, чем во время токсичной жратвы кажется исследование больших гигеровских башен на луне и маленьких киберпанковых игр про Алису, когда безмолвно сделал 19 двойных шагов вспять".
Room1={}
Room2={}
currentRoom=Room1
function Room1:doSomething()
print ("Вы уходите из комнаты 1 в комнату 2!")
currentRoom=Room2
end
function Room2:doSomething()
print ("Вы в комнате 2!")
end
currentRoom:doSomething()
currentRoom:doSomething()
На выходе будет
Вы уходите из комнаты 1 в комнату 2! Вы в комнате 2!
Ну это просто пример, чтобы показать принцип. goto не особо нужно для такого. При желании можно сделать класс комнаты. Масса вариантов.
зачем тебе godot если есть switch? или нет? или есть? lua ведь хорош еще использованием метатаблиц:
alexsilent = { [1] = function (x) print(11) end,
[2] = function (x) w = 5 end,
["nop"] = function (x) print("i love godot") end,
["my name"] = function (x) print("i need godot") end,
}
А, была книга Д. Гибсона - "Искусство сведения". Вот там написано про пространство в композиции, хорошая концепция. Опять же, может есть лучше книги, или хуже, но тут вроде более-менее норм.
Там FAQ внизу страницы джема есть. В некоторых движках считается, что так нельзя или частично нельзя (из-за лого в начале), и есть на этот счёт исключения.
а юнити слишком мощный для этого...
Нет, народ делает на чём угодно, в т.ч. 3д-игры обтягивает пиксельным шейдером. :D
на Годот пиксели не достаточно точные
extends Camera2D
# based on: https://www.reddit.com/r/godot/comments/abrvjf/pixel_perfect_camera_for_everyone/
### Base Size of the Game ###
const BaseW = 544
const BaseH = 307
signal updateZoom
var black = Color(0.20,0.0,0.41,1)
### OS Size of the Window ###
var ScreenW
var ScreenH
### The Pixel Resizer ###
var MaxResize
### Camera Zoom ###
var CameraW
var CameraH
### Black Bars ###
var BlackX
var BlackY
func set_color4(color):
black = color
VisualServer.set_default_clear_color(color)
func _ready():
doStuff()
#get_tree().root.set_size_override_stretch(false)
func _process(delta):
doStuff()
func doStuff():
#get the device's screen size/resolution
ScreenW = OS.get_window_size().x
ScreenH = OS.get_window_size().y
#get the shortest, if length or width of the screen as a basis to resize
var compx = max(floor(ScreenW/BaseW), 1.0)
var compy = max(floor(ScreenH/BaseH), 1.0)
if (compx <= compy):
MaxResize = compx
else:
MaxResize = compy
CameraW = (BaseW*ScreenW)/(BaseW*MaxResize)
CameraH = (BaseH*ScreenH)/(BaseH*MaxResize)
var zoom = 1.0 / MaxResize
set_zoom(Vector2(zoom, zoom))
emit_signal("updateZoom", MaxResize)
#Calculate the black bar size
BlackX = (CameraW-BaseW)/2
BlackY = (CameraH-BaseH)/2
С пиксельными UI-нодами, я, правда, не разобрался до конца, это только для обычных спрайтов.
Да кто тебе сказал что комнаты должны иметь абсолютно правильные геометрические размеры? Игрок что, с лупой будет лазать и мерять линейкой размер комнаты и проверять - совпадает ли он с размером на карте?
Квадратные комнаты делали только потому чтобы более экономно использовать память приставки, разбивая весь мир на фрагменты одинакового размера. Сейчас ты можешь делать уровни любых размеров и формы.
Если у тебя не рандомный мир, то карта уровней вообще может быть одной отдельной картинкой, которую ты сам потом нарисовал. В итоге в игре вся структура уровней будет формироваться только с помощью переходов между комнатами. Останется в самой комнате хранить координаты ее верх. левого угла на миникарте (или номер клетки по X, Y, если у тебя все комнаты кратны размеру клетки). Тогда точку персонажа на миникарте рисуешь исходя из этих координат и координат персонажа в самой комнате.
У меня в DrawColor у каждой комнаты было 4 границы перехода - верхняя, нижняя, левая, правая. При пересечении границы код попадал в обработчик комнаты и он, в зависимости от того в какой точке игрок пересек границу, решал - в какую комнату, в какую ее точку перенести персонажа. Это все прописывалось жесткой логикой, поскольку размеры комнат могли иметь любой размер (но всегда были только прямоугольными, AABB). Если обработчик возвращал "1", то перехода не происходило и персонаж как будто утыкался в стену. Могло вернуться "0", если там пустота и "-1", если персонаж должен сразу погибнуть (например, падение в пропасть). Если же обработчик вернул список с названием комнаты и координатами, то персонаж переносился в эту комнату, в заданные координаты. Координаты выбирались так, чтобы оказаться на небольшом расстоянии (~10 пикселей) от края экрана. Список всех комнат хранился глобально. Все противники и предметы при выходе из комнаты - удалялись, при входе - создавались заново (как в Смоле).
До реализации миникарты дело еще не дошло, есть только рисунок в Гимпе. Пока эта игра заморожена.
https://blender3d.com.ua/dvigok-renderinga-freestyle/
вот тут в кратце есть подобные линии на объекте в Blender.
У него и курс есть по Freestyle в Blender 2.7
В твиттере попадалось вот это https://adventofcode.com/ и такое https://www.codingame.com
Ещё, например, конкурсы на Shadertoy
Ещё демосцена всё ещё жива, но надо туда по идее ехать вживую (например, в РФ Chaos Constructions)
геймджемы же xD
Ещё blocktober вспомнил
По правде, я ненавижу многие нововведения ГМС2, равно как и ГМС1, но с этим приходится работать, чтобы выходить на последние платформы, включая HTML5, Android, iOS, Xbox One, PS4 и Nintendo Switch. А скомпилированное в ГМ8.1 работает на Windows XP прекрасно, т. к. он ещё и сам шёл на Windows XP. Найди где-нибудь в интернете, скажем тут, и пробуй. Если что непонятно, проконсультирую.
Чтобы вычислить? Ну как в калькуляторе нужно сначала вбить первое число, иначе с чем работать? Надо его в ячейку записать, это я и обозначил как "загрузить".
Нет, в переменной к этому моменту уже есть нужное нам число. Мы загружаем это число ИЗ переменной в регистр - потому что только в регистре могут происходить вычисления. Переменная это просто что-то где-то в оперативной памяти, тогда как регистр - физически существующая (в реальном мире, а не в магическом мире программирования) в процессоре (да, в той квадратной штуке вставленной в материнскую плату твоего компьютера) ячейка куда попадает нужное количество электронов, чтобы представлять собой нужное число.
Есть, без них никуда.
Хорошие новости - есть. Плохие новости - без goto в ассемблере невозможно сделать цикл for, да и никакой другой цикл тоже. Потому что цикл в нём делается так:
Вместо 10 можно загрузить любую переменную.
В си-подобном коде это было бы:
Нет и нет. Про for я уже показал выше, а всё что ты пишешь в if например так:
Должно вычисляться в ассемблере поштучно и по порядку:
А если у тебя больше проверок в условии, будь добр считай их все по очереди пока не просчитаешь до конца всё. Есть автоматизированные способы это делать: https://ru.wikipedia.org/wiki/Обратная_польская_запись#Пример_вычисления_выражений
Мораль: оно тебе надо? :yak:
Важный факт: "Hello World" это программа, которую никто и никогда не пишет с нуля. Все Хэллоу Ворлды копируются с уже существующих предыдущих, поэтому задача состоит в копировании, а не в придумывании всех заклинаний, обрамляющих то что программисту на самом деле нужно от компьютера. Я имею в виду, если программа должна выводить одну строку, то она и должна состоять из одной строки. А на практике на том же C# тебе нужно писать:
Да, в современных IDE это всё сразу в шаблоне пустого проекта, но сколько мусора приходится видеть на экране, и сколько раз вычислять нужное среди ненужного?
https://excelwithbusiness.com/blog/say-hello-world-in-28-different-programming-languages/ - вот кстати подборка хэллоуворлдов на разных языках. Однако, где короче всего пишется хэллоуворлд, там совсем не факт что удобно делать игру, да и вообще компьютерную программу. Вот вариант для ассемблера собственно:
Я это к чему - чтобы освоить язык и/или платформу, нужно просто работать по уже существующим примерам. Ты себя просто недооцениваешь, другое дело что мотивация работать с ассемблером будет неминуемо падать, учитывая сколько времени требуется на написание программы на нём. И в целом рекомендации на нём делать игры я дать не имею оснований.
Начни, может, с музыки для NES, раз уж речь о ней?
http://www.famitracker.com
Для твоих диалогов: Ссылка
Еще пример:
На первый вопрос - нет, Awake\Update не могут ничего ждать (они должны выполниться за время одного кадра), но в Awake\Update можно выполнить
а в Dialog объявленной выше уже ждать.
На второй вопрос - да, можно ждать переменных.
Вот краткое описание: https://habr.com/ru/post/216185/
Далеко не уходи: https://docs.godotengine.org/ru/latest/getting_started/scripting/gdscript/gdscript_basics.html#coroutines-with-yield
Можно по имени переключать, положи их в одну директорию, и делай get_tree().change_scene("res://path/to/scene.tscn"), где путь склеиваешь из постоянной директории и переменного названия уровня.
Вот ещё какой-то пример есть для посложнее, но это к Антонке, наверное, мне такое не пригождалось ещё.
Тема гаминатора: "Не то, чем во время токсичной жратвы кажется исследование больших гигеровских башен на луне и маленьких киберпанковых игр про Алису, когда безмолвно сделал 19 двойных шагов вспять".
В Firefox можно включить контейнеры для вкладок https://support.mozilla.org/ru/kb/kontejnery
А если так?
https://superuser.com/a/723145
https://toster.ru/answer?answer_id=131183#answers_list_answer
https://natureofcode.com/book/chapter-3-oscillation/
Вот тригонометрия с околоигровыми примерами, как один из вариантов.
Ну, подозреваю, что как-то так
Ну а то, что я писал выше, может выглядеть так:
На выходе будет
Ну это просто пример, чтобы показать принцип. goto не особо нужно для такого. При желании можно сделать класс комнаты. Масса вариантов.
зачем тебе godot если есть switch? или нет? или есть? lua ведь хорош еще использованием метатаблиц:
https://m.habr.com/ru/post/466641/
Почему это нет!? Очень даже есть:
- тыц, тыц, тыц, ты-дыщ
А вот такой пробовал? Там вроде ретро, но с возможностью выбора, и луа. По описанию звучит, как будто прям для тебя делали.
И вот ещё почитай список. :)
Бывают, напишешь не совсем корректно шейдер, на современной видеокарте (драйвере) проглотит, а на старой - ошибка может вылезти.
А, была книга Д. Гибсона - "Искусство сведения". Вот там написано про пространство в композиции, хорошая концепция. Опять же, может есть лучше книги, или хуже, но тут вроде более-менее норм.
Об опере. И еще немного об опере. Если правда интересно про композицию, то в академическую музыку придется минимум окунуться.
https://soundcloud.com/shemusic
https://soundcloud.com/iamwontolla
https://soundcloud.com/leafadventure
https://soundcloud.com/fark
https://soundcloud.com/johnfn (более ранние композы)
https://soundcloud.com/ddrkirbyisq (более ранние композы)
https://soundcloud.com/motherchip
https://soundcloud.com/cosmochild
https://soundcloud.com/jooel-2
https://soundcloud.com/feintdnb (есть немного похожего)
https://soundcloud.com/electricjoyride (есть немного похожего)
А чем отличается пиксельарт в PS от пиксельарта в любой другой программе? То есть проще искать уроки по пиксельарту в принципе.
Погугли "книжки" Pixel Logic, они полезные. Ещё на https://lospec.com/ посмотри, там агрегируется всякое.
Там FAQ внизу страницы джема есть. В некоторых движках считается, что так нельзя или частично нельзя (из-за лого в начале), и есть на этот счёт исключения.
Нет, народ делает на чём угодно, в т.ч. 3д-игры обтягивает пиксельным шейдером. :D
С пиксельными UI-нодами, я, правда, не разобрался до конца, это только для обычных спрайтов.
Да кто тебе сказал что комнаты должны иметь абсолютно правильные геометрические размеры? Игрок что, с лупой будет лазать и мерять линейкой размер комнаты и проверять - совпадает ли он с размером на карте?
Квадратные комнаты делали только потому чтобы более экономно использовать память приставки, разбивая весь мир на фрагменты одинакового размера. Сейчас ты можешь делать уровни любых размеров и формы.
Если у тебя не рандомный мир, то карта уровней вообще может быть одной отдельной картинкой, которую ты сам потом нарисовал. В итоге в игре вся структура уровней будет формироваться только с помощью переходов между комнатами. Останется в самой комнате хранить координаты ее верх. левого угла на миникарте (или номер клетки по X, Y, если у тебя все комнаты кратны размеру клетки). Тогда точку персонажа на миникарте рисуешь исходя из этих координат и координат персонажа в самой комнате.
У меня в DrawColor у каждой комнаты было 4 границы перехода - верхняя, нижняя, левая, правая. При пересечении границы код попадал в обработчик комнаты и он, в зависимости от того в какой точке игрок пересек границу, решал - в какую комнату, в какую ее точку перенести персонажа. Это все прописывалось жесткой логикой, поскольку размеры комнат могли иметь любой размер (но всегда были только прямоугольными, AABB). Если обработчик возвращал "1", то перехода не происходило и персонаж как будто утыкался в стену. Могло вернуться "0", если там пустота и "-1", если персонаж должен сразу погибнуть (например, падение в пропасть).
Если же обработчик вернул список с названием комнаты и координатами, то персонаж переносился в эту комнату, в заданные координаты. Координаты выбирались так, чтобы оказаться на небольшом расстоянии (~10 пикселей) от края экрана.
Список всех комнат хранился глобально. Все противники и предметы при выходе из комнаты - удалялись, при входе - создавались заново (как в Смоле).
До реализации миникарты дело еще не дошло, есть только рисунок в Гимпе. Пока эта игра заморожена.