В теме 11 сообщений

Новичок

Всём ещё раз здравствуйте. 

Вообщем начал я разработку своего проекта и понял... Я ничерта не понял. Я смотрел видео. Читал книги. Решил попробовать сделать тдм сервер в точности по видео и у меня не получилось. В видео он сохранил несколько позиций спавна в массив и потом через функцию по очерёдности i++ доставал эти позиции, то есть каждый игрок должен был появляться на следующей позиции. Я сделал всё в точности как у него, прям всё. У меня сравнится на нулевых координатах с id3 скином, хотя в массиве совершенно другие скины. Откуда он берёт точку спавна и скин, почему не достаёт значения из массива я так понять и не смог, хотя сделал всё в точности как у него. По конец даже комментарии и координаты скопировал, ну ничего не помогает. Видео 8ми летней давности, может оно уже не актуально для нынешнего времени, может сейчас новая версия pawn и там совершенно по другому я так и не разобрался. Пожалуйста, подскажите мне что делать. Я прочитал несколько книг про Pawno. Сейчас я хочу сесть и делать код по каким то примерам с объяснениями, но в просторах интернета нету новых уроков по Pawno. Старые я не решаюсь смотреть т.к. думаю что это всё же проблема в том что раньше был другой синтаксис. Помогите пожалуйста

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Cawfee
Великий Гуру

@KeinKotov, синтаксис языка может меняться только при появлении новых компиляторов, причем меняться с обратной совместимостью: старые варианты написания будут работать на новых компиляторах. И, как правило, эти новые компиляторы лишь устраняли баги стандартного (например, зависание при отсутствии парной фигурной скобки). Единственная проблема, с которой вы можете столкнуться, руководствуясь старыми уроками, так это применение неактуальных технологий, но насколько целесообразно гнаться за иными сейчас? Качество подаваемого материала – что раньше, что сейчас – оставляет желать лучшего, так что довольствуемся имеющимся. Видеоурок, статья или книга – все это лишь готовая информация, которую вы читаете и на основе нее познаете (или не познаете), используя разные методы (см. методы познания). Каждый человек один и тот же материал может понять совершенно по-разному. Это зависит от подачи и применяемых вами методов (большинство методов вы применяете неосознанно). Те методы, которые хороши для одного человека, не подходят другому в силу его особенностей.

 

Здорово, что нашли материал про разные позиции для появления игрока, что реализовали, но коль уж столкнулись с трудностью, почему бы не приложить исходный текст вашей разработки, чтобы обсудить проблему с другими участниками форума?

 

Если хотите, можем обменяться контактами, чем смогу помогу, коль уж так заинтересованы. В противном случае случае будем рады видеть ваши вопросы здесь :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Новичок

@Cawfee Конечно,у меня чистый мод,это единственное что я сделал

new Float:SpawnInfo[6][5]=
{//skins,x,y,z,f
(106.0,-2165.8843,-266.2318,36.5156,2.5948), // PosBand 1
(104.0,-2170.1770,-265.9297,36.5156,6.7320),
(123.0,-2177.6699,-262.9620,36.5156,271.5822),
(280.0,-2139.9097,-108.1546,35.3273,11.9411), // PosCop 1
(268.0,-2145.7178,-108.3139,35.3203,1.5604),
(265.0,-2150.6736,-108.2174,35.3203,0.8293)
};
main()
{
    print("\n----------------------------------");
    print(" Blank Gamemode by your name here");
    print("----------------------------------\n");
}

public OnGameModeInit()
{
    SetGameModeText("Blank Script");
    
    for(new i; i <= sizeof(SpawnInfo); i++)
    {
        AddPlayerClass(floatround(SpawnInfo[i][0]), SpawnInfo[i][1], SpawnInfo[i][2], SpawnInfo[i][3], SpawnInfo[i][4], 2410000000);
    }
    return 1;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Завсегдатый

@KeinKotov 

Ты бы начал с написания регистрации/авторизации, работой с MySQL. Есть много уроков в ютубе - ознакомься.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Новичок

@sinvays С этого проще начать? Я слышал что лучше сначала написать какой нибудь простенький дм, потом уже изучать mysql, бд и так далее. Я уже создал простенький тдм по видео и сейчас добавляю туда свои системы. Пока что трудно без интернета, но думаю что скоро приловчусь. Если хотите то финальный результат могу выложить. Так же планирую залить его на хостинг и поиграть с друзьями, если им понравиться то это будем дополнительной мотивацией

Отредактировано пользователем KeinKotov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Cawfee
Великий Гуру

@KeinKotov, прекрасно.

 

Рассмотрим формирование вами двумерного массива с описанием классов, подлежащих выбору игроком.

new Float:SpawnInfo[6][5]=
{   //skins,x,y,z,f
    (106.0,-2165.8843,-266.2318,36.5156,2.5948), // PosBand 1
    (104.0,-2170.1770,-265.9297,36.5156,6.7320),
    (123.0,-2177.6699,-262.9620,36.5156,271.5822),
    (280.0,-2139.9097,-108.1546,35.3273,11.9411), // PosCop 1
    (268.0,-2145.7178,-108.3139,35.3203,1.5604),
    (265.0,-2150.6736,-108.2174,35.3203,0.8293)
};

Синтаксис языка предполагает, что перечисление элементов массива должно быть заключено в фигурные скобки. В данном же случае используются круглые скобки, которые меняют поведение компилятора, разбирающего приведенный фрагмент кода. В Pawn есть оператор "запятая", который является оператором множественного присваивания. У оператора запятой есть одна особенность: возвращаемым значением всегда является результат самого правого выражения. Пример – далее.

new b = 1;
new a = (b, 8)
// в a будет записано 8, над b выполнена пустая операция

В вашем же случае компилятор в каждой строке разглядывает применение такого оператора и считает, что в каждой строке описан только один элемент измерения массива – последний элемент. То есть при таком синтаксисе компилятор считает, что в ячейках [строка][0] лежит значение [строка][5], а все остальные элементы массива не описаны и по умолчанию получают значение 0. Таким образом, компилятору ваш массив представляется следующим образом. 

new Float:SpawnInfo[6][5]=
{   //skins,x,y,z,f
    {2.59480000}, // PosBand 1
    {6.73200000},
    {271.58220000},
    {11.94110000}, // PosCop 1
    {1.56040000},
    {0.82930000}
};

А далее уже эти некорректные данные используются как аргументы функции AddPlayerClass, что влечет выдачу неправильных скинов и появление на нулевых координатах. Все, что требуется для устранения проблемы, – так это лишь поставить фигурные скобки вместо круглых:

new Float:SpawnInfo[6][5]=
{   //skins,x,y,z,f
    {106.0,-2165.8843,-266.2318,36.5156,2.5948}, // PosBand 1
    {104.0,-2170.1770,-265.9297,36.5156,6.7320},
    {123.0,-2177.6699,-262.9620,36.5156,271.5822},
    {280.0,-2139.9097,-108.1546,35.3273,11.9411}, // PosCop 1
    {268.0,-2145.7178,-108.3139,35.3203,1.5604},
    {265.0,-2150.6736,-108.2174,35.3203,0.8293}
};

 

Остальной код комментировать пока не берусь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Новичок

@Cawfee Ого, спасибо большое за такое подробное объяснение. Я пытался решить эту задачу через ИИ и потерял пару часов своей жизни. В итоге я просто закинул ему код, он что то изменил и у меня всё сработало, ещё минут 20 я посидел и пытался найти то что он исправил(я случайно закрыл страницу с ИИ и тем что было и старого кода у меня не было), я искал в чем же была моя ошибка но кроме табуляции списка ничего не нашел, так и не разобравшись в чем была причина я продолжил. Теперь благодаря вам я буду знать эту на вид мелочь но столь значимую вещь

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Создатель WayDev

Помимо того, что @Cawfee уже разобрал, особо добавить и нечего. Единственное, что могу добавить - комбинировать данные в двумерном массиве можно и работать с этим научиться можно уже сейчас. В Pawn есть tag override operator (или же оператор переопределения тега). С какой конкретно версии pawn-компилятора работает данный оператор - сказать не могу, но с 3.10.8 точно работает.

Пример работы с данным оператором:

// _: - tag override operator (оператор переопределения тега).

// двумерный массив
new SpawnInfo[6][5]=
{   //skins,x,y,z,f
    {106, _:-2165.8843, _:-266.2318, _:36.5156, _:2.5948}, // PosBand 1
    {104, _:-2170.1770, _:-265.9297, _:36.5156, _:6.7320},
    {123, _:-2177.6699, _:-262.9620, _:36.5156, _:271.5822},
    {280, _:-2139.9097, _:-108.1546, _:35.3273, _:11.9411}, // PosCop 1
    {268, _:-2145.7178, _:-108.3139, _:35.3203, _:1.5604},
    {265, _:-2150.6736, _:-108.2174, _:35.3203, _:0.8293}
};

// использование:
SetPlayerSkin(playerid, SpawnInfo[0][0]); // значение типа integer (целое число) используем как обычно.
SetPlayerPos(playerid, Float:SpawnInfo[0][1], Float:SpawnInfo[0][2], Float:SpawnInfo[0][3]); // в данном случае мы определяем тип значения.

Данный оператор помогает комбинировать данные без использования лишних энумераторов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Новичок

@𝙡𝙖𝙨𝙩 𝙚𝙢𝙥𝙚𝙧𝙤𝙧. Большое спасибо, но я не совсем поняли его использование, как SetPlayerPos поймёт что ему нужно каждый раз вставлять новое значение? Для чего [1], [2]... в начале строк? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Cawfee
Великий Гуру

@KeinKotov, SetPlayerPos ничего не понимает, это всего лишь имя функции, реализованной в библиотеке мультиплеера. Давайте сразу для себя уясним, что исходный текст, который вы пишете в своем редакторе (например, в стандартном редакторе Pawno) на языке Pawn и помещаете в файлы с расширением .pwn, должен быть скомпилирован при помощи компилятора pawncc. Заметьте: язык называется Pawn, а редактор – Pawno. Процесс компиляции есть преобразование исходных текстов, понятных человеку, в машинный код, понятный, соответственно, машине. Машиной может выступать как другая программа, которая будет обрабатывать машинный код (например, Java-машина), так и процессор. В нашей же объектной области исходные тексты компилируются в файлы с расширением .amx и выполняются так называемой amx-машиной (фактически это тоже программа, которая интерпретирует инструкции в .amx файле, а инструкции самой amx-машины выполняет уже центральный процессор вашего персонального компьютера).

 

Элементами любого вычислительного устройства являются процессор (выполняет инструкции из оперативной памяти), оперативная память (куда загружаются программы для исполнения и данные), а также устройства ввода-вывода (клавиатура и монитор, например) для того, чтобы можно было задавать начальные данные и получать выходные. Ваш массив SpawnInfo в конечном счете будет помещен в память, а операндами исполняемых инструкций являются данные из этой памяти, что фактически обеспечивает "взятие" оттуда данных для их использования, скажем, в SetPlayerPos. Компилятор (как минимум) должен понимать, сколько места занимает ваш массив SpawnInfo (хотя бы для того, чтобы убедиться, возможно ли его разместить в памяти). Любая переменная, любой элемент массива, любой символ занимают в нашей объектной области одну ячейку. Ячейка – специфическое понятие, кое редко можно встретить в компилируемых языках программирования. Следует просто помнить, что ячейка равна четырем байтам для SA:MP и CR:MP. Давайте рассмотрим для примера следующий массив:

new array[5] = {12345};

Очевидно, это массив, состоящий из целых чисел (можно сказать, что тип данных элементов массива – целочисленный, но в Pawn некорректно говорить о типах данных, этот вопрос затронем позже). Размерность массива – 5 элементов. Учитывая, что каждый элемент занимает одну ячейку, то размер массива составляет 5 ячеек. Если вспомним, что размер каждой ячейки составляет 4 байта, то размер данного массива – 5*4 = 20 байтов (если вы не знакомы с понятиями бит и байт, необходимо ознакомиться, иначе дальнейший текст будет непонятен). В памяти это может иметь следующее размещение (будем считать, что слева представлен не абсолютный адрес, а относительный, то есть смещение относительно адреса начала массива в памяти):

000001 00 00 00
000402 00 00 00
000803 00 00 00
001204 00 00 00 
001605 00 00 00

Почему такое размещение данных в памяти? В нашем компиляторе, как и в привычных нам процессорах x86, используется формат хранения данных в памяти little-endian. Это означает, что по старшему адресу размещается старший байт числа (и, соответственно, по младшему адресу размещается младший байт числа). Поскольку число 1 в десятеричной системе счисления есть 0x00'00'00'01 в шестнадцатеричной, то младший байт 0x01 размещается по младшему адресу 00h, а старшие три байта (нулевые) размещаются по старшим адресам 01h - 03h. То же самое касается и чисел 02, 03, 04, 05. Для сравнения рассмотрим размещение в памяти следующего массива:

new array[5] = {0x112233440x556677880x99AABBCC0xDDEEFF000x12345678};

000044 33 22 11
000488 77 66 55
0008: CC BB AA 99
0012: FF EE FF 00 
001612 34 56 78

Как видите, массив занимает все те же 5 ячеек (20 байтов), но теперь уже старшие байты (которые ранее были незначащими и нулевыми), играют какую-то роль. И, поскольку ячейка ограничена 4 байтами, максимальное число, которое мы можем разместить в ячейке, это 0xFF'FF'FF'FF, что равно (2^32 - 1) в десятеричной системе.

 

Если говорить про адресацию элементов одномерного массива, то любой доступ к массиву рассматривается как "нужно взять начало массива и сместиться на N ячеек". Пока amx-машина исполняет инструкции вашего игрового мода, она понятия не имеет, есть ли в памяти массивы, или это просто набор переменных, она не знает и о размерностях массива, иными словами, amx-машина видит лишь набор данных, а что это за данные она не знает. Это связано с тем, что компилятор, когда преобразует исходные тексты в инструкции, выполняет преобразования примерно следующего вида:

// исходный массив:
new array[5] = {0x112233440x556677880x99AABBCC0xDDEEFF000x12345678};

// ячейка, к которой вы обращаетесь в своем исходном тексте
array[3]

// как это обращение преобразуется компилятором
(array + 3// array - адрес начала массива, 3 - на сколько ячеек нужно сместиться вперед
// таким образом, в приведенном выше примере будет осуществлен доступ к ячейке, имеющей
// значение 0xDDEEFF00

Теперь рассмотрим двумерный массив, например, такой:

new array[3][2] = {
    {1122},
    {3344},
    {5566}
};

Очевидно, размер массива составляет 3х2 = 6 ячеек, или 24 байта. Доступ к ним осуществляется по формуле: array + (i * 2 + j), где i - первое измерение, j - второе. Обращаясь к элементу array[2][1], мы фактически обращаемся к ячейке (2 * 2 + 1) = 5, или к байтам (20h – 23h). В памяти элементы хранятся тоже последовательно, можете сравнить полученный расчет для array[2][1] с "дампом" памяти, и убедиться, что мы в двух случаях обращаемся к ячейке со значением 66.

000011 00 00 00
000422 00 00 00
000833 00 00 00
001244 00 00 00 
001655 00 00 00
002066 00 00 00

Возвращаясь к вашему вопросу:

3 часа назад, KeinKotov сказал:

Для чего [1], [2]... в начале строк?

Таким образом вы указываете, к каким элементам двумерного массива осуществляется обращение. Первые квадратные скобки есть индексация по одному измерению (в данном случае по строкам), вторые квадратные скобки - по другому (в данном случае по столбцам). В вашем исходном тексте в функции AddPlayerClass в первых скобках индексом по первому измерению выступала переменная, что как раз обеспечивало проход по всем строкам массива: данные из каждой строки были полезно использованы в определении классов игрока.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Новичок

@Cawfee спасибо ещё раз большое, с первого раза не всё понял:) , но я прочту подробнее про процессоры,компиляцию,биты и байты, и ещё раз прочту, если ещё раз не пойму то прочту ещё раз. Спасибо большое за вашу помощь. Всё ваши сообщения, хоть и кажется трудно понимаемыми, я пытаюсь понять до единого слова, всё что вы мне пишете я изучаю, анализирую, тестирую. Если я что то не понял, я обязательно добьюсь того чтоб всё понять

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!


Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.


Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

  • Похожий контент

    • От Smileee
      Куплю мобильный проект, что бы был интересный и не слитый, что то интересное. Пишите в личные
    • От KeinKotov
      Всем привет. Меня зовут Kein. Я первый день на вашем форуме.
      Хочу поделиться с вами своей историей о моей пути в скриптинге сампа и создании своего сервера, историей которая только началась.
      Мне 22 года, работаю на стройке, есть жена и полугодовалая дочь. В скриптинг я пошёл потому что всегда любил самп, играл в него лет с 12, но на данный момент у меня большие хотелки к серверам сампа и нечего подходящего я найти не могу. Идей для реализации механик у меня полно, а слушать меня никто не хочет. Вот я и принял решение изучить скриптинг и создать свой сервер. Я уже понял насколько это тяжело, но я взялся за это основательно. Сервер с оригинальным модом будет открыт. Только неизвестно когда, учить мне ещё много.
      Вот собственно поэтому я и решил вести блог тут, я хочу делиться своими успехами, рассказывать о том что нашёл на просторах интернета или придумал сам, да и новичкам начинать будет проще видя мой путь. На данный момент с pawn я знаком только по лп "Основы pawn" на канале "PawnStart" И читаю книгу "PawnBook v5".Подскажите пожалуйста, если я не правильно начал изучать pawn, то что следует сделать первым делом?
      Я обещаю что я открою свой сервер, так что следите за дальнейшими постами. Всех обнял
    • От maximBO$$
      не могу скачать файлы сервера, ошибки на скрине
      функциями 0.3дл на сервере пользоваться не могу
       
      фото ошибок
       

    • От Козельский Ярослав
      Люди, скажите пожалуйста, где мне взять основу для лаунчера который можно будет выставить в магазин приложений после изменения дизайна и ip серверов?
    • От _goshich_
      "Хочу создать свой CRMP-сервер в стиле Amazing RP, Rodina RP или Malinovka RP. Подскажите:
      1. На какой версии SA-MP или CRMP работают эти проекты? (0.3.7, 0.3.DL, OpenMP?) "Скажите пожалуйста точную версию"
      2. Какие базовые файлы и моды нужно скачать для старта? (движок, плагины, скрипты).
      3. Есть ли готовые шаблоны под RP-геймплей (фракции, экономика, бизнесы)?