1

So I have a project in GameMaker, which has a chatbox. The messages for this are stored in an array. I would like to be able to scroll through this array, so I can view earlier chat messages.

This is what I currently have:

Create Event

chatLog[0] = "";
chatIndex  = 0;

Step Event

if (chatIndex > 0) {
    if (mouse_wheel_down()) {
        chatIndex--;
    }
}

if (chatIndex < array_length_1d(chatLog) - 1) {
    if (mouse_wheel_up()) {
        chatIndex++;
    }
}

var _maxLines = 5;
for (i = 0; i < _maxLines; i++) {
    if (i > (array_length_1d(chatLog) - 1)) { exit; }

    var _chatLength = array_length_1d(chatLog) - 1;
    draw_text(0, 50 - chatHeight, chatLog[_chatLength - i + chatIndex]);
}
Halden Collier
  • 845
  • 7
  • 18

1 Answers1

1

First, for convenience of being able to add messages to front / remove them from the back (once there are too many), let's suppose that the log is a list, item 0 being the newest message,

chatLog = ds_list_create();
chatIndex = 0;
for (var i = 1; i <= 15; i++) {
    ds_list_insert(chatLog, 0, "message " + string(i));
}

then, the Step Draw event can use information from the list to clamp scroll offset range and draw items:

var maxLines = 5;
// scrolling:
var dz = (mouse_wheel_up() - mouse_wheel_down()) * 3;
if (dz != 0) {
    chatIndex = clamp(chatIndex + dz, 0, ds_list_size(chatLog) - maxLines);
}
// drawing:
var i = chatIndex;
var _x = 40;
var _y = 200;
repeat (maxLines) {
    var m = chatLog[|i++];
    if (m == undefined) break; // reached the end of the list
    draw_text(_x, _y, m);
    _y -= string_height(m); // draw the next item above the current one
}

live demo

YellowAfterlife
  • 2,967
  • 1
  • 16
  • 24
  • 1
    Awesome! A few things in there I did think about myself, for example using a `ds_list` rather than an `array`. Like the added feature of being able to scroll by a set increment. Thanks a lot for your help, all works perfectly in my project! :) – Halden Collier Aug 29 '19 at 13:50